百億數據量下,掌握這些Redis技巧你大概就穩住了全場

1、Redis封裝架構講解程序員

實際上NewLife.Redis是一個完整的Redis協議功能的實現,可是Redis的核心功能並無在這裏面,而是在NewLife.Core裏面。面試

這裏能夠打開看一下,NewLife.Core裏面有一個NewLife.Caching的命名空間,裏面有一個Redis類,裏面實現了Redis的基本功能;另外一個類是RedisClient是Redis的客戶端。數據庫

Redis的核心功能就是有這兩個類實現,RedisClient表明着Redis客戶端對服務器的一個鏈接。Redis真正使用的時候有一個Redis鏈接池,裏面存放着不少個RedisClient對象。json

 

因此咱們Redis的封裝有兩層,一層是NewLife.Core裏面的Redis以及RedisClient;另外一層就是NewLife.Redis。這裏面的FullRedis是對Redis的實現了Redis的全部的高級功能。緩存

這裏你也能夠認爲NewLife.Redis是Redis的一個擴展。服務器

2、Test實例講解Redis的基本使用網絡

一、實例多線程

打開Program.cs看下代碼:架構

 

這裏XTrace.UseConsole();是向控制檯輸出日誌,方便調試使用查看結果。併發

接下來看第一個例子Test1,具體的我都在代碼中進行了註釋,你們能夠看下:

 

 

Set的時候,若是是字符串或者字符數據的話,Redis會直接保存起來(字符串內部機制也是保存二進制),若是是其餘類型,會默認進行json序列化而後再保存起來。

Get的時候,若是是字符串或者字符數據會直接獲取,若是是其餘類型會進行json反序列化。

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移除。

二、壓力測試

接下來看第四個例子,咱們直接作壓力測試,代碼以下:

 

 

運行的結果以下圖所示:

測試就是進行get,set remove,累加等的操做。你們能夠看到在我本機上輕輕鬆鬆的到了六十萬,多線程的時候甚至到了一百多萬。

爲何會達到這麼高的Ops呢?下面給你們說一下:

Bench會分根據線程數分多組進行添刪改壓力測試;

rand參數,是否隨機產生key/value;

batch批大小,分批執行讀寫操做,藉助GetAll/SetAll進行優化。

三、Redis中NB的函數來提高性能

上面的操做若是你們都掌握了就基本算Redis入門了,接下來進行進階。若是能全然吃透,差很少就會比別人更勝一籌了。

GetAll()與SetAll()

GetAll:比方說我要取十個key,這個時候能夠用getall。這時候Redis就執行了一次命令。比方說我要取10個key那麼用get的話要取10次,若是用getall的話要用1次。1次getall時間大概是get的一點幾倍,可是10次get的話就是10倍的時間,這個帳你應該會算吧?強烈推薦你們用getall。

setall跟getall類似,批量設置K-V。

setall與getall性能很恐怖,官方公佈的Ops也就10萬左右,爲何咱們的測試輕輕鬆鬆到五十萬甚至上百萬?由於咱們就用了setall,getall。若是get,set兩次以上,建議用getall,setall。

Redis管道Pipelin

好比執行10次命令會打包成一個包集體發過去執行,這裏實現的方式是StartPipeline()開始,StopPipeline()結束中間的代碼就會以管道的形式執行。

這裏推薦使用更強的武器,AutoPipeline自動管道屬性。管道操做到必定數量時,自動提交,默認0。使用了AutoPipeline,就不須要StartPipeline,StopPipeline指定管道的開始結束了。

Add與Replace

Add:Redis中沒有這個Key就添加,有了就不要添加,返回false;

Replace:有則替換,還會返回原來的值,沒有則不進行操做。

Add跟Replace就是實現Redis分佈式鎖的關鍵。

3、Redis使用技巧,經驗分享

在項目的Readme中,這裏摘錄下:

一、特性

在ZTO大數據實時計算普遍應用,200多個Redis實例穩定工做一年多,天天處理近1億包裹數據,日均調用量80億次;

低延遲,Get/Set操做平均耗時200~600us(含往返網絡通訊);

大吞吐,自帶鏈接池,最大支持1000併發;

高性能,支持二進制序列化(默認用的json,json很低效,轉成二進制性能會提高不少)。

二、Redis經驗分享

在Linux上多實例部署,實例個數等於處理器個數,各實例最大內存直接爲本機物理內存,避免單個實例內存撐爆(比方說8核心處理器,那麼就部署8個實例)。

把海量數據(10億+)根據key哈希(Crc16/Crc32)存放在多個實例上,讀寫性能成倍增加。

採用二進制序列化,而很是見的Json序列化。

合理設計每一對Key的Value大小,包括但不限於使用批量獲取,原則是讓每次網絡包控制在1.4k字節附近,減小通訊次數(實際經驗幾十k,幾百k也是沒問題的)。

Redis客戶端的Get/Set操做平均耗時200~600us(含往返網絡通訊),以此爲參考評估網絡環境和Redis客戶端組件(達不到就看一下網絡,序列化方式等等)。

使用管道Pipeline合併一批命令。

Redis的主要性能瓶頸是序列化、網絡帶寬和內存大小,濫用時處理器也會達到瓶頸。

其它可查優化技巧。

以上經驗,源自於300多個實例4T以上空間一年多穩定工做的經驗,並按照重要程度排了前後順序,可根據場景須要酌情采用。

三、緩存Redis的兄弟姐妹

Redis實現ICache接口,它的孿生兄弟MemoryCache,內存緩存,千萬級吞吐率。

各應用強烈建議使用ICache接口編碼設計,小數據時使用MemoryCache實現;數據增大(10萬)之後,改用Redis實現,不須要修改業務代碼。

4、關於一些疑問的回覆

這一Part咱們會來聊聊大數據中Redis使用的經驗:

Q1:一條數據多個key怎麼設置比較合理?

A1:若是對性能要求不是很高直接用json序列化實體就好,不必使用字典進行存儲。

 

Q2:隊列跟List有什麼區別?左進右出的話用List仍是用隊列比較好?

A2:隊列其實就是用List實現的,也是基於List封裝的。左進右出的話直接隊列就好。Redis的List結構比較有意思,既能夠左進右出,也能右進左出。因此它既能夠實現列表結構,也能隊列,還能實現棧。

 

Q3:存放多個字段的類性能同樣嗎?

A3:大部分場景都不會有誤差,可能對於大公司數據量比較大的場景會有些誤差。

 

Q4:大數據寫入到數據庫以後,好比數據到億以上的時候,統計分析、查詢這塊,能不能分享些經驗。

A4:分表分庫,拆分到一千萬之內。

 

Q5:CPU爲什麼暴漲?

A5:程序員終極理念——CPU達到百分百,而後性能達到最優,儘可能不要浪費。最痛恨的是——若是CPU不到百分百,性能無法提高了,說明代碼有問題。

 

雖然Redis你們會用,可是咱們可能平時不會有像這樣的大數據使用場景。但願本文可以給你們一些值得借鑑的經驗。

相關文章
相關標籤/搜索