做者:依樂祝
原文地址:http://www.javashuo.com/article/p-btlvrxjc-do.htmlhtml
熟悉的開場白,你們晚上好啊,今天給你們分享的是Redis在大數據中的使用,可能真正講的是一些redis的使用技巧,Redis基本的一些東西。git
首先給你們個地址,源碼以及實例都在裏面,固然今天的分享也是按照裏面的實例來進行的,你們能夠先進行下載。
http://git.newlifex.com/NewLife/NewLife.Redis
固然這裏也附上Redis的下載地址:
windows:https://github.com/MicrosoftArchive/redis/releases
http://x.newlifex.com/Redis-x64-3.2.100.msi
Linux:https://redis.io/download程序員
實際上NewLife.Redis是一個完整的Redis協議的功能的實現,可是redis的核心功能並無在這裏面,Redis的核心功能的實現是在NewLife.Core裏面。這裏能夠打開看一下,NewLife.Core裏面有一個NewLife.Caching的命名空間,裏面有一個Redis類裏面實現了Redis的基本功能,另外一個類是RedisClient是Redis的客戶端。Redis的核心功能就是有這兩個類實現。RedisClient表明着Redis客戶端對服務器的一個鏈接。Redis真正使用的時候有一個Redis鏈接池,裏面存放着不少個RedisClient對象。github
因此咱們Redis的封裝有兩層,一層是NewLife.Core裏面的Redis以及RedisClient。另外一層就是NewLife.Redis。這裏面的FullRedis是對Redis的實現了Redis的全部的高級功能。這裏你也能夠認爲NewLife.Redis是Redis的一個擴展。面試
打開Program.cs看下代碼redis
這裏XTrace.UseConsole();
是向控制檯輸出日誌,方便調試使用查看結果。數據庫
接下來看第一個例子Test1。具體的我都在代碼中進行了註釋,你們能夠看下json
static void Test1() { var ic = Redis.Create("127.0.0.1:6379", 3);//建立Redis實例,獲得FullRedis對象 //var ic = new FullRedis();//另外一種實例化的方式 //ic.Server = "127.0.0.1:6379"; //ic.Db = 3;//Redis中數據庫 ic.Log = XTrace.Log;//顯示日誌,進行Redis操做把日誌輸出,生產環境不用輸出日誌 // 簡單操做 Console.WriteLine("共有緩存對象 {0} 個", ic.Count);//緩存對象數量 ic.Set("name", "大石頭");//Set K-V結構,Set第二個參數能夠是任何類型 Console.WriteLine(ic.Get<String>("name"));//Get泛型,指定獲取的類型 ic.Set("time", DateTime.Now, 1);//過時時間秒 Console.WriteLine(ic.Get<DateTime>("time").ToFullString()); Thread.Sleep(1100); Console.WriteLine(ic.Get<DateTime>("time").ToFullString()); // 列表 var list = ic.GetList<DateTime>("list"); list.Add(DateTime.Now); list.Add(DateTime.Now.Date); list.RemoveAt(1); Console.WriteLine(list[list.Count - 1].ToFullString()); // 字典 var dic = ic.GetDictionary<DateTime>("dic"); dic.Add("xxx", DateTime.Now); Console.WriteLine(dic["xxx"].ToFullString()); // 隊列 var mq = ic.GetQueue<String>("queue"); mq.Add(new[] { "abc", "g", "e", "m" }); var arr = mq.Take(3); Console.WriteLine(arr.Join(",")); // 集合 var set = ic.GetSet<String>("181110_1234"); set.Add("xx1"); set.Add("xx2"); set.Add("xx3"); Console.WriteLine(set.Count); Console.WriteLine(set.Contains("xx2")); Console.WriteLine("共有緩存對象 {0} 個", ic.Count); }
Set的時候若是是字符串或者字符數據的話Redis會直接保存起來(字符串內部機制也是保存二進制),若是是其餘類型會默認進行json序列化而後再保存起來c#
Get的時候若是是字符串或者字符數據會直接獲取,若是是其餘類型會進行json反序列化windows
Set第三個參數過時時間單位是秒。
vs調試小技巧,按F5或者直接工具欄「啓動」會編譯整個解決方案會很慢(VS默認),能夠選中項目而後右鍵菜單選擇調試->啓動新實例。會只編譯將會用到的項目,這樣對調試來講會快不少。
你們運行調試後能夠看到控制檯輸出的內容:向右的箭頭=》是
ic.Log=XTrace.Log
輸出的日誌字典的使用:對象的話須要把json所有取出來而後轉換成對象,而字典的話就能夠直接取某個字段。
隊列是List結構實現的,使用場景能夠上游數據太多,下游處理不過來的時候,那麼就可使用這個隊列。上游的數據發到隊列,而後下游慢慢的消費。另外一個應用,跨語言的協同工做,比方說其餘語言實現的程序往隊列裏面塞數據,而後另外一種語言來進行消費處理。哈,這種方式相似mq的概念,雖然有點low,可是也很好用。
集合,用的比較多的是用在一個須要精確判斷的去重功能。像咱們天天有三千萬訂單,這三千萬訂單能夠有重複,這時候我想統計下一共有訂單,這時候直接數據庫group by是不大可能的,由於數據庫中分了十幾張表,這裏分享個實戰經驗:比方說攬收,商家發貨了,網點要把件收回來,可是收回來以前網點不知道本身有多少貨啊,這時候咱們作了一個功能,也就是訂單會發送到咱們公司來,咱們會建一個time_site的key的集合,並且集合自己有去重的功能,並且咱們能夠很方便的經過set.Count功能來統計數量,當件被攬收之後,咱們後臺把這個件從集合中Remove掉.而後這個Set中存在的就是網點尚未攬收的件,這時候經過Count就會知道這個網點今天還有多少件沒有攬收。實際使用中這個數量比較大,由於有幾萬個網點。
Redis中布隆過濾器,去重的,面試的時候問的比較多
小經驗分享:
- 數據庫中不合法的時間處理:判斷時間中的年份,是否大於2000年。若是小於2000就認爲不合法。習慣大於小於號不習慣用等於號,這樣能夠處理不少意外的數據
- Set的時候最好指定過時時間防止有些須要刪除的數據,咱們忘記刪了
- Redis異步儘可能不用,由於Redis延遲自己很小,大概在100us-200us,再一個就是Redis自己是單線程的,異步任務切換的耗時比網絡耗時還要大。
- List用法:物聯網中數據上傳,量比較大時,咱們能夠把這些數據先放在Redis的List中,好比說一秒鐘1萬條,而後再批量取出來而後批量插入數據庫中。這時候要設置好key,能夠前綴+時間,對於已經處理的List能夠進行remove移除。
接下來看第四個例子,咱們直接作壓力測試,代碼以下:
static void Main(String[] args) { XTrace.UseConsole(); // 激活FullRedis,不然Redis.Create會獲得默認的Redis對象 FullRedis.Register(); Test4(); Console.ReadKey(); } static void Test4() { var ic = Redis.Create("127.0.0.1:6379", 5); //var ic = new MemoryCache(); ic.Bench(); }
運行的結果以下圖所示:
測試就是進行get,set remove,累加等的操做。你們能夠看到在我本機上輕輕鬆鬆的到了六十萬,多線程的時候甚至到了一百多萬。爲何會達到這麼高的ops呢,下面給你們說一下。
上面的操做若是你們都掌握的基本算Redis入門了,接下來進行進階。會了基本比別人更勝一籌了。
GetAll:比方說我要取十個key,這個時候能夠用getall。這時候redis就執行了一次命令。比方說我要取10個key那麼用get的話要取10次,若是用getall的話要用1次。一次getall時間大概是get的一點幾倍,可是10次get的話就是10倍的時間,這個帳你應該會算吧。強烈推薦你們用getall。
setall 跟getall類似。批量設置K-V.
setall與getall性能很恐怖,官方公佈的ops也就10萬左右,爲何咱們的測試輕輕鬆鬆到五十萬甚至上百萬,由於咱們就用了setall,getall。
若是get,set兩次以上,建議用getall,setall
好比執行10次命令會打包成一個包集體發過去執行,這裏實現的方式是StartPipeline()開始,StopPipeline()結束中間的代碼就會以管道的形式執行。這裏推薦使用咱們的更強的武器,AutoPipeline自動管道屬性。管道操做到必定數量時,自動提交,默認0。使用了AutoPipeline,就不須要StartPipeline,StopPipeline指定管道的開始結束了!
Add跟Replace就是實現Redis分佈式鎖的關鍵
在項目的Readme中,這裏摘錄下:
Redis實現ICache接口,它的孿生兄弟MemoryCache,內存緩存,千萬級吞吐率。
各應用強烈建議使用ICache接口編碼設計,小數據時使用MemoryCache實現;
數據增大(10萬)之後,改用Redis實現,不須要修改業務代碼。
一條數據多個key怎麼設置比較合理?
若是對性能要求不是很高直接用json序列化實體就好,不必使用字典進行存儲。
隊列跟List有什麼區別?左進右出的話用List仍是用隊列比較好?
隊列其實就是用List實現的,也是基於List封裝的。左進右出的話直接隊列就好。Redis的List結構比較有意思,既能夠左進右出,也能右進左出。因此它既能夠實現列表結構,也能隊列,也能實現棧
存放多個字段的類性能同樣嗎?
大部分場景都不會有誤差,可能對於大公司數據量比較大的場景會有些誤差
能否介紹一下使用Redis進行數據計算、統計的場景?
略。本身看視頻吧!o(∩_∩)o 哈哈!(由於我沒聽清!)
大數據寫入到數據庫以後 好比數據到億以上的時候 統計分析這塊 查詢這塊 能不能分享些經驗。
分表分庫,拆分到一千萬之內。
CPU爲什麼暴漲?
程序員終極理念:CPU達到百分百,而後性能達到最優,儘可能不要浪費。最痛恨的是:若是cpu不到百分百,性能無法提高了,說明代碼有問題!
視頻已經上傳至百度雲,你們能夠自行下載觀看
連接:https://pan.baidu.com/s/1sOW_PLjxQE8C2msbDfizeA
提取碼:c7dp
觀看指南(笑笑提供)
雖然Redis會用,可是沒有像大石頭這樣的大數據使用場景。今天的視頻收穫頗豐,可能大部分人跟我同樣,沒有大石頭的使用場景,可是值得借鑑的經驗仍是很豐富的!期待下一次的精彩分享。同時附上QQ羣:1600800。能夠共同交流使用經驗!