Redis學習--總結(jié)

初識redis

1)Redis的8個特性:速度快、基于鍵值對的數(shù)據(jù)結(jié)構(gòu)服務器俏扩、功能豐富糜工、簡單穩(wěn)定、客戶端語言多录淡、持久化捌木、主從復制、支持高可用和分布式嫉戚。
2)Redis并不是萬金油刨裆,有些場景不適合使用Redis進行開發(fā)。
3)開發(fā)運維結(jié)合以及閱讀源碼是用好Redis的重要方法彬檀。
4)生產(chǎn)環(huán)境中使用配置文件啟動Redis帆啃。
5)生產(chǎn)環(huán)境選取穩(wěn)定版本的Redis。
6)Redis3.0是重要的里程碑凤覆,發(fā)布了Redis官方的分布式實現(xiàn)Redis Cluster链瓦。

API的理解和使用

1)Redis提供5種數(shù)據(jù)結(jié)構(gòu),每種數(shù)據(jù)結(jié)構(gòu)都有多種內(nèi)部編碼實現(xiàn)盯桦。
2)純內(nèi)存存儲慈俯、IO多路復用技術(shù)、單線程架構(gòu)是造就Redis高性能的三個因素拥峦。
3)由于Redis的單線程架構(gòu)贴膘,所以需要每個命令能被快速執(zhí)行完,否則會存在阻塞Redis的可能略号,理解Redis單線程命令處理機制是開發(fā)和運維Redis的核心之一刑峡。
4)批量操作(例如mget、mset玄柠、hmset等)能夠有效提高命令執(zhí)行的效率突梦,但要注意每次批量操作的個數(shù)和字節(jié)數(shù)。
5)了解每個命令的時間復雜度在開發(fā)中至關重要羽利,例如在使用keys宫患、hgetall、smembers这弧、zrange等時間復雜度較高的命令時娃闲,需要考慮數(shù)據(jù)規(guī)模對于Redis的影響。
6)persist命令可以刪除任意類型鍵的過期時間匾浪,但是set命令也會刪除字符串類型鍵的過期時間皇帮,這在開發(fā)時容易被忽視。
7)move蛋辈、dump+restore属拾、migrate是Redis發(fā)展過程中三種遷移鍵的方式,其中move命令基本廢棄,migrate命令用原子性的方式實現(xiàn)了dump+restore捌年,并且支持批量操作瓢娜,是Redis Cluster實現(xiàn)水平擴容的重要工具。
8)scan命令可以解決keys命令可能帶來的阻塞問題礼预,同時Redis還提供了hscan眠砾、sscan、zscan漸進式地遍歷hash托酸、set褒颈、zset。

小功能大用處

1)慢查詢中的兩個重要參數(shù)slowlog-log-slower-than和slowlog-maxlen励堡。
2)慢查詢不包含命令網(wǎng)絡傳輸和排隊時間谷丸。
3)有必要將慢查詢定期存放。
4)redis-cli一些重要的選項应结,例如--latency刨疼、–-bigkeys、-i和-r組合鹅龄。
5)redis-benchmark的使用方法和重要參數(shù)揩慕。
6)Pipeline可以有效減少RTT次數(shù),但每次Pipeline的命令數(shù)量不能無節(jié)制扮休。
7)Redis可以使用Lua腳本創(chuàng)造出原子迎卤、高效、自定義命令組合玷坠。
8)Redis執(zhí)行Lua腳本有兩種方法:eval和evalsha蜗搔。
9)Bitmaps可以用來做獨立用戶統(tǒng)計,有效節(jié)省內(nèi)存八堡。
10)Bitmaps中setbit一個大的偏移量樟凄,由于申請大量內(nèi)存會導致阻塞。
11)HyperLogLog雖然在統(tǒng)計獨立總量時存在一定的誤差兄渺,但是節(jié)省的內(nèi)存量十分驚人不同。
12)Redis的發(fā)布訂閱機制相比許多專業(yè)的消息隊列系統(tǒng)功能較弱,不具備堆積和回溯消息的能力溶耘,但勝在足夠簡單。
13)Redis3.2提供了GEO功能服鹅,用來實現(xiàn)基于地理位置信息的應用凳兵,但底層實現(xiàn)是zset。

客戶端

1)RESP(Redis Serialization Protocol Redis)保證客戶端與服務端的正常通信企软,是各種編程語言開發(fā)客戶端的基礎庐扫。
2)要選擇社區(qū)活躍客戶端,在實際項目中使用穩(wěn)定版本的客戶端。
3)區(qū)分Jedis直連和連接池的區(qū)別形庭,在生產(chǎn)環(huán)境中铅辞,應該使用連接池。
4)Jedis.close()在直連下是關閉連接萨醒,在連接池則是歸還連接斟珊。
5)Jedis客戶端沒有內(nèi)置序列化,需要自己選用富纸。
6)客戶端輸入緩沖區(qū)不能配置囤踩,強制限制在1G之內(nèi),但是不會受到maxmemory限制晓褪。
7)客戶端輸出緩沖區(qū)支持普通客戶端堵漱、發(fā)布訂閱客戶端、復制客戶端配置涣仿,同樣會受到maxmemory限制勤庐。
8)Redis的timeout配置可以自動關閉閑置客戶端,tcp-keepalive參數(shù)可以周期性檢查關閉無效TCP連接
9)monitor命令雖然好用好港,但是在大并發(fā)下存在輸出緩沖區(qū)暴漲的可能性愉镰。
10)info clients幫助開發(fā)和運維人員找到客戶端可能存在的問題。
11)理解Redis通信原理和建立完善的監(jiān)控系統(tǒng)對快速定位解決客戶端常見問題非常有幫助媚狰。

持久化

1)Redis提供了兩種持久化方式:RDB和AOF岛杀。
2)RDB使用一次性生成內(nèi)存快照的方式,產(chǎn)生的文件緊湊壓縮比更高崭孤,因此讀取RDB恢復速度更快类嗤。由于每次生成RDB開銷較大,無法做到實時持久化辨宠,一般用于數(shù)據(jù)冷備和復制傳輸遗锣。
3)save命令會阻塞主線程不建議使用,bgsave命令通過fork操作創(chuàng)建子進程生成RDB避免阻塞嗤形。
4)AOF通過追加寫命令到文件實現(xiàn)持久化精偿,通過appendfsync參數(shù)可以控制實時/秒級持久化。因為需要不斷追加寫命令赋兵,所以AOF文件體積逐漸變大笔咽,需要定期執(zhí)行重寫操作來降低文件體積。
5)AOF重寫可以通過auto-aof-rewrite-min-size和auto-aof-rewritepercentage參數(shù)控制自動觸發(fā)霹期,也可以使用bgrewriteaof命令手動觸發(fā)叶组。
6)子進程執(zhí)行期間使用copy-on-write機制與父進程共享內(nèi)存,避免內(nèi)存消耗翻倍历造。AOF重寫期間還需要維護重寫緩沖區(qū)甩十,保存新的寫入命令避免數(shù)據(jù)丟失船庇。
7)持久化阻塞主線程場景有:fork阻塞和AOF追加阻塞。fork阻塞時間跟內(nèi)存量和系統(tǒng)有關侣监,AOF追加阻塞說明硬盤資源緊張鸭轮。
8)單機下部署多個實例時,為了防止出現(xiàn)多個子進程執(zhí)行重寫操作橄霉,建議做隔離控制窃爷,避免CPU和IO資源競爭。

復制

1)Redis通過復制功能實現(xiàn)主節(jié)點的多個副本酪劫。從節(jié)點可靈活地通過slaveof命令建立或斷開復制流程吞鸭。
2)復制支持樹狀結(jié)構(gòu),從節(jié)點可以復制另一個從節(jié)點覆糟,實現(xiàn)一層層向下的復制流刻剥。Redis2.8之后復制的流程分為:全量復制和部分復制。全量復制需要同步全部主節(jié)點的數(shù)據(jù)集滩字,大量消耗機器和網(wǎng)絡資源造虏。而部分復制有效減少因網(wǎng)絡異常等原因造成的不必要全量復制情況。通過配置合理的復制積壓緩沖區(qū)盡量避免全量復制麦箍。
3)主從節(jié)點之間維護心跳和偏移量檢查機制漓藕,保證主從節(jié)點通信正常和數(shù)據(jù)一致。
4)Redis為了保證高性能復制過程是異步的挟裂,寫命令處理完后直接返回給客戶端享钞,不等待從節(jié)點復制完成。因此從節(jié)點數(shù)據(jù)集會有延遲情況诀蓉。
5)當使用從節(jié)點用于讀寫分離時會存在數(shù)據(jù)延遲栗竖、過期數(shù)據(jù)、從節(jié)點可用性等問題渠啤,需要根據(jù)自身業(yè)務提前作出規(guī)避狐肢。
6)在運維過程中,主節(jié)點存在多個從節(jié)點或者一臺機器上部署大量主節(jié)點的情況下沥曹,會有復制風暴的風險份名。

Redis的噩夢:阻塞

1)客戶端最先感知阻塞等Redis超時行為,加入日志監(jiān)控報警工具可快速定位阻塞問題妓美,同時需要對Redis進程和機器做全面監(jiān)控僵腺。
2)阻塞的內(nèi)在原因:確認主線程是否存在阻塞,檢查慢查詢等信息壶栋,發(fā)現(xiàn)不合理使用API或數(shù)據(jù)結(jié)構(gòu)的情況想邦,如keys、sort委刘、hgetall等丧没。關注CPU使用率防止單核跑滿。當硬盤IO資源緊張時锡移,AOF追加也會阻塞主線程呕童。
3)阻塞的外在原因:從CPU競爭、內(nèi)存交換淆珊、網(wǎng)絡問題等方面入手排查是否因為系統(tǒng)層面問題引起阻塞夺饲。

理解內(nèi)存

1)Redis實際內(nèi)存消耗主要包括:鍵值對象、緩沖區(qū)內(nèi)存施符、內(nèi)存碎片往声。
2)通過調(diào)整maxmemory控制Redis最大可用內(nèi)存。當內(nèi)存使用超出時戳吝,根據(jù)maxmemory-policy控制內(nèi)存回收策略浩销。
3)內(nèi)存是相對寶貴的資源,通過合理的優(yōu)化可以有效地降低內(nèi)存的使用量听哭,內(nèi)存優(yōu)化的思路包括:

  • 精簡鍵值對大小慢洋,鍵值字面量精簡,使用高效二進制序列化工具陆盘。
  • 使用對象共享池優(yōu)化小整數(shù)對象普筹。
  • 數(shù)據(jù)優(yōu)先使用整數(shù),比字符串類型更節(jié)省空間隘马。
  • 優(yōu)化字符串使用太防,避免預分配造成的內(nèi)存浪費。
  • 使用ziplist壓縮編碼優(yōu)化hash酸员、list等結(jié)構(gòu)蜒车,注重效率和空間的平衡。
  • 使用intset編碼優(yōu)化整數(shù)集合沸呐。
  • 使用ziplist編碼的hash結(jié)構(gòu)降低小對象鏈規(guī)模醇王。
哨兵

1)Redis Sentinel是Redis的高可用實現(xiàn)方案:故障發(fā)現(xiàn)、故障自動轉(zhuǎn)移崭添、配置中心寓娩、客戶端通知。
2)Redis Sentinel從Redis2.8版本開始才正式生產(chǎn)可用呼渣,之前版本生產(chǎn)不可用棘伴。
3)盡可能在不同物理機上部署Redis Sentinel所有節(jié)點。
4)Redis Sentinel中的Sentinel節(jié)點個數(shù)應該為大于等于3且最好為奇數(shù)屁置。
5)Redis Sentinel中的數(shù)據(jù)節(jié)點與普通數(shù)據(jù)節(jié)點沒有區(qū)別焊夸。
6)客戶端初始化時連接的是Sentinel節(jié)點集合,不再是具體的Redis節(jié)點蓝角,但Sentinel只是配置中心不是代理阱穗。
7)Redis Sentinel通過三個定時任務實現(xiàn)了Sentinel節(jié)點對于主節(jié)點饭冬、從節(jié)點、其余Sentinel節(jié)點的監(jiān)控揪阶。
8)Redis Sentinel在對節(jié)點做失敗判定時分為主觀下線和客觀下線昌抠。
9)看懂Redis Sentinel故障轉(zhuǎn)移日志對于Redis Sentnel以及問題排查非常有幫助。
10)Redis Sentinel實現(xiàn)讀寫分離高可用可以依賴Sentinel節(jié)點的消息通知鲁僚,獲取Redis數(shù)據(jù)節(jié)點的狀態(tài)變化炊苫。

集群

1)Redis集群數(shù)據(jù)分區(qū)規(guī)則采用虛擬槽方式,所有的鍵映射到16384個槽中冰沙,每個節(jié)點負責一部分槽和相關數(shù)據(jù)侨艾,實現(xiàn)數(shù)據(jù)和請求的負載均衡。
2)搭建集群劃分三個步驟:準備節(jié)點拓挥,節(jié)點握手唠梨,分配槽∽策矗可以使用redis-trib.rb create命令快速搭建集群姻成。
3)集群內(nèi)部節(jié)點通信采用Gossip協(xié)議彼此發(fā)送消息,消息類型分為:ping消息愿棋、pong消息科展、meet消息、fail消息等糠雨。節(jié)點定期不斷發(fā)送和接受ping/pong消息來維護更新集群的狀態(tài)才睹。消息內(nèi)容包括節(jié)點自身數(shù)據(jù)和部分其他節(jié)點的狀態(tài)數(shù)據(jù)。
4)集群伸縮通過在節(jié)點之間移動槽和相關數(shù)據(jù)實現(xiàn)甘邀。擴容時根據(jù)槽遷移計劃把槽從源節(jié)點遷移到目標節(jié)點琅攘,源節(jié)點負責的槽相比之前變少從而達到集群擴容的目的,收縮時如果下線的節(jié)點有負責的槽需要遷移到其他節(jié)點松邪,再通過cluster forget命令讓集群內(nèi)其他節(jié)點忘記被下線節(jié)點坞琴。
5)使用Smart客戶端操作集群達到通信效率最大化,客戶端內(nèi)部負責計算維護鍵→槽→節(jié)點的映射逗抑,用于快速定位鍵命令到目標節(jié)點剧辐。集群協(xié)議通過Smart客戶端全面高效的支持需要一個過程,用戶在選擇Smart客戶端時建議review下集群交互代碼如:異常判定和重試邏輯邮府,更新槽的并發(fā)控制等荧关。節(jié)點接收到鍵命令時會判斷相關的槽是否由自身節(jié)點負責,如果不是則返回重定向信息褂傀。重定向分為MOVED和ASK忍啤,ASK說明集群正在進行槽數(shù)據(jù)遷移,客戶端只在本次請求中做臨時重定向仙辟,不會更新本地槽緩存同波。MOVED重定向說明槽已經(jīng)明確分派到另一個節(jié)點鳄梅,客戶端需要更新槽節(jié)點緩存。
6)集群自動故障轉(zhuǎn)移過程分為故障發(fā)現(xiàn)和故障恢復参萄。節(jié)點下線分為主觀下線和客觀下線卫枝,當超過半數(shù)主節(jié)點認為故障節(jié)點為主觀下線時標記它為客觀下線狀態(tài)。從節(jié)點負責對客觀下線的主節(jié)點觸發(fā)故障恢復流程讹挎,保證集群的可用性。
7)開發(fā)和運維集群過程中常見問題包括:超大規(guī)模集群帶寬消耗吆玖,pub/sub廣播問題筒溃,集群節(jié)點傾斜問題,手動故障轉(zhuǎn)移沾乘,在線遷移數(shù)據(jù)等怜奖。

緩存設計

1)緩存的使用帶來的收益是能夠加速讀寫,降低后端存儲負載翅阵。
2)緩存的使用帶來的成本是緩存和存儲數(shù)據(jù)不一致性歪玲,代碼維護成本增大,架構(gòu)復雜度增大掷匠。
3)比較推薦的緩存更新策略是結(jié)合剔除滥崩、超時、主動更新三種方案共同完成讹语。
4)穿透問題:使用緩存空對象和布隆過濾器來解決钙皮,注意它們各自的使用場景和局限性。
5)無底洞問題:分布式緩存中顽决,有更多的機器不保證有更高的性能短条。有四種批量操作方式:串行命令、串行IO才菠、并行IO茸时、hash_tag。
6)雪崩問題:緩存層高可用赋访、客戶端降級可都、提前演練是解決雪崩問題的重要方法。
7)熱點key問題:互斥鎖进每、“永遠不過期”能夠在一定程度上解決熱點key問題汹粤,開發(fā)人員在使用時要了解它們各自的使用成本。

開發(fā)運維的“陷阱”

1)Linux相關優(yōu)化:

  • vm.overcommit_memory建議為1田晚。
  • Linux>3.5嘱兼,vm.swappiness建議為1,否則建議為0贤徒。
  • Transparent Huge Pages(THP)建議關閉掉芹壕,但需要注意Linux發(fā)行版本改變了THP的配置位置汇四。
  • 可以為Redis進程設置oom_adj,減少Redis被OOM killer殺掉的概率踢涌,但不要過度依賴此特性通孽。
  • 建議對Redis所有節(jié)點所在機器使用NTP服務。
  • 設置合理的ulimit保證網(wǎng)絡連接正常睁壁。
  • 設置合理的tcp-backlog參數(shù)背苦。

2)理解Redis的持久化有助于解決flush操作之后的數(shù)據(jù)快速恢復問題。
3)Redis安全建議:

  • 根據(jù)具體網(wǎng)絡環(huán)境決定是否設置Redis密碼潘明。
  • rename-command可以偽裝命令行剂,但是要注意成本。
  • 合理的防火墻是防止攻擊的利器钳降。
  • bind可以將Redis的訪問綁定到指定網(wǎng)卡上厚宰。
  • 定期備份數(shù)據(jù)應該作為習慣性操作。
  • 可以適當錯開Redis默認端口啟動遂填。
  • 使用非root用戶啟動Redis铲觉。

4)bigkey的危害不容忽視:數(shù)據(jù)傾斜、超時阻塞吓坚、網(wǎng)絡擁塞撵幽,可能是Redis生產(chǎn)環(huán)境中的一顆定時炸彈,刪除bigkey時通常使用漸進式遍歷的方式凌唬,防止出現(xiàn)Redis阻塞的情況并齐。
5)通過客戶端、代理客税、monitor况褪、機器抓包四種方式找到熱點key,這幾種方式各具優(yōu)勢更耻,具體使用哪種要根據(jù)當前場景來決定测垛。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市秧均,隨后出現(xiàn)的幾起案子食侮,更是在濱河造成了極大的恐慌,老刑警劉巖目胡,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锯七,死亡現(xiàn)場離奇詭異,居然都是意外死亡誉己,警方通過查閱死者的電腦和手機眉尸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人噪猾,你說我怎么就攤上這事霉祸。” “怎么了袱蜡?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵丝蹭,是天一觀的道長。 經(jīng)常有香客問我坪蚁,道長奔穿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任敏晤,我火速辦了婚禮巫橄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茵典。我一直安慰自己,他們只是感情好宾舅,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布统阿。 她就那樣靜靜地躺著,像睡著了一般筹我。 火紅的嫁衣襯著肌膚如雪扶平。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天蔬蕊,我揣著相機與錄音结澄,去河邊找鬼。 笑死岸夯,一個胖子當著我的面吹牛麻献,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播猜扮,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼勉吻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旅赢?” 一聲冷哼從身側(cè)響起齿桃,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煮盼,沒想到半個月后短纵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡僵控,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年香到,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡养渴,死狀恐怖雷绢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情理卑,我是刑警寧澤翘紊,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站藐唠,受9級特大地震影響帆疟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宇立,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一踪宠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妈嘹,春花似錦柳琢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至毙驯,卻和暖如春倒堕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背爆价。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工垦巴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铭段。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓骤宣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稠项。 傳聞我的和親對象是個殘疾皇子涯雅,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • Redis是什么? Redis是Nosql的一種展运,以key-value形式存儲于內(nèi)存中的數(shù)據(jù)庫.提供了 Strin...
    whoami2019閱讀 640評論 0 10
  • 本文是對Redis的集群部署模式一個學習總結(jié)活逆,共包括如下章節(jié)內(nèi)容: 概述 主從集群模式 “哨兵”集群模式 Clus...
    我是老薛閱讀 934評論 0 4
  • 1. Redis Sentinel 簡介 redis 的主從復制模式下,一旦主節(jié)點由于故障不能提供服務拗胜,需要人工將...
    CoderJed閱讀 2,771評論 0 11
  • 最近又復習了一下redis中比較重要的幾個知識點,知識點多且碎,在這里做一個簡單的總結(jié),便于以后復習蔗候。 主流應用架...
    lhsjohn閱讀 969評論 1 2
  • markdown與我 對于markdown語法,我可謂是一見鐘情了埂软,這種小巧輕量的文本標記語言锈遥,能夠快速地實現(xiàn)一些...
    kuohao閱讀 238評論 0 0