redis叢集討論

來源:互聯網
上載者:User

標籤:

一、生產應用情境二、儲存架構演變三、應用最佳實務四、營運經驗總結


第1、2節:介紹redis cluster在唯品會的生產應用情境,以及儲存架構的演變。
第3節:redis cluster的穩定性,應用成熟度等級,踩到過那些坑,如何解決這些問題?這部分是大家比較關心的內容。
第4節:簡單介紹大規模運營的一些經驗,包括部署、監控、管理以及redis工具開發。

一、生產應用情境1、業務範圍

redis cluster在唯品會主要應用於後端業務,用作記憶體儲存服務。主要大資料即時推薦/ETL、風控、營銷三大業使用。cluster用於取代當前twemproxy三層架構,作為通用的儲存架構。redis cluster可以大幅度簡化我們的儲存架構,也解決twemproxy架構無法線上擴容節點的問題。目前我們線上有生產幾十個cluster叢集,約2千個instances,單個叢集最大達到250+instances。
這是我們的生產應用情境,主要是後端業務的儲存,目前沒有作為cache使用的情境。

2、大資料、風控、營銷系統的特徵
  • cluster作為資料量大, 單個cluster叢集在幾十個GB到上TB層級記憶體儲存量。
  • 作為後端應用的儲存,資料來源主要以下三種方式:

    • Kafka --> Redis Cluster,Storm/Spark即時
    • Hive --> Redis Cluster, MapReduce程式
    • MySQL --> Redis Cluster,Java/C++程式。
  • 資料由離線/即時job產生, 讀寫請求量大, 對讀寫效能也要求高。

  • 業務高峰期請求量急劇上升,幾倍的讀寫量增加,需要多個redis執行個體承擔業務的讀寫壓力。
  • 業務需求變化快, schema變化頻繁。如果使用MySQL作為儲存,那麼將會是頻繁的DLL變更,而且需要做online schema change。
  • 大促銷活動時擴容頻繁。
3、為什麼選擇redis cluster3.1 cluster適合我們後端生產應用情境
  • 線上水平擴充能力,能夠解決我們大量的擴容需求。
  • Failover能力和高可用性。
  • 雖然cluster不保證主從資料強一致性,但是後端業務能夠容忍failover後少量的資料丟失。
3.2 架構簡單
  • 無中心架構,各個節點度等。slave節點提供資料冗餘,master節點異常時提升為master。
  • 取代twemproxy三層架構,系統複雜性降低。
  • 可以節約大量的硬體資源,我們的Lvs + Twemproxy層 使用了近上千台物理機器。
  • 少了lvs和twemproxy層,讀寫效能提升明顯。回應時間從100-200us減少到50-100us。
  • 系統瓶頸更少。lvs層網卡和pps輸送量瓶頸;對於請求長度較大的業務,twemproxy單節點效能低。
    總結下,我們選擇redis cluster主要這兩點原因:簡單、擴充性。另外,我們用cluster取代twemproxy叢集,三層架構實在是很令人頭疼,複雜、瓶頸多、管理不方面。
二、儲存架構演變1、架構演變

 

在2014年7月,為了準備當時的814撒嬌節大促銷活動,我們把單個redis的服務遷移到twemproxy上。twemproxy在後端快速完成資料分區和擴容。為了避免再次擴容,我們靜態分配足夠多的資源。
之後,twemproxy暴露出來的系統瓶頸很多,資源使用很多,也存在一定的浪費。我們決定用redis cluster取代這種複雜的三層架構。
redis cluster GA之後,我們就開始上線使用。最初是3.0.2 版本,後面大量使用3.0.3 ,上個月開始使用3.0.7版本。

下面簡單對比下兩種架構,解析下他們的優缺點。

2、Twemproxy架構優點
  • sharding邏輯對開發透明,讀寫方式和單個redis一致。
  • 可以作為cache和storage的proxy(by auto-eject)。
缺點
  • 架構複雜,層次多。包括lvs、twemproxy、redis、sentinel和其控制層程式。
  • 管理成本和硬體成本很高。
  • 2 * 1Gbps 網卡的lvs機器,最大能支撐140萬pps。
  • 流量高的系統,proxy節點數和redis個數接近。
  • Redis層仍然擴容能力差,預分配足夠的redis儲存節點。

 

這是twemproxy的架構,用戶端直接連接最上面的lvs(LB),第二層是同構的twemproxy節點,下面的redis master節點以及熱備的slave節點,另外還有獨立的sentinel叢集和切換控製程序,twemproxy先介紹到這裡。

3、Redis Cluster架構優點
  • 無中心 架構。
  • 資料按照slot儲存分布在多個redis執行個體上。
  • 增加slave做standby資料副本,用於failover,使叢集快速恢複。
  • 實現故障auto failover。節點之間通過gossip協議交換狀態資訊;投票機制完成slave到master角色的提升。
  • 亦可manual failover,為升級和遷移提供可操作方案。
  • 降低硬體成本和營運成本,提高系統的擴充性和可用性。
缺點
  • client實現複雜,驅動要求實現smart client,緩衝slots mapping資訊並及時更新。
  • 目前僅JedisCluster相對成熟,異常處理部分還不完善,比如常見的“max redirect exception”。
  • 用戶端的不成熟,影響應用的穩定性,提高開發難度。
  • 節點會因為某些原因發生阻塞(阻塞時間大於clutser-node-timeout),被判斷下線。這種failover是沒有必要,sentinel也存在這種切換情境。
    cluster的架構如下:

cluster.jpg

圖上只有master節點(slave略去),所有節點構成一個完全圖,slave節點在叢集中與master只有角色和功能的區別。

架構演變講完了,開始講第三部分,也是大家最感興趣的一部分.

三、應用最佳實務
  • redis cluster的穩定性如何?
  • 存在哪些坑?
  • develop guideline & best practice
1、穩定性
  • 不擴容時叢集非常穩定。
  • 擴容resharding時候,早期版本的Jedis端有時會出現“max-redirect”異常。
    分析Jedis源碼,請求重試次數達到了上限,仍然沒有請求成功。兩方面分析:redis串連不上?還是叢集節點資訊不一致?
  • 存活檢測機制缺陷
    redis 存活檢測機制可能因為master 節點上慢查詢、阻塞式命令、或者其它的效能問題導致長時間沒有響應,這個節點會認為處於failed狀態,並進行切換。這種切換是沒必要的。最佳化策略:a) 預設的cluster-node-timeout為15s,可以適當增大;
    b) 避免使用會引起長時間阻塞的命令,比如save/flushdb等阻塞操作,或者keys pattern這種慢查詢。

總體來說,redis cluster已經非常穩定了,但是要注意一些應用中的小問題,下面是5個坑,大家注意了.

2、有哪些坑?2.1 遷移過程中Jedis“Max Redirect”異常。
  • github上討論的結果是程式retry。
  • max redirt issues:https://github.com/xetorthio/jedis/issues/1238
  • retry時間應該大於failover 時間。
  • Jedis參數最佳化調整:增大jedis中的‘DEFAULT_MAX_REDIRECTIONS’參數,預設值是5.
  • 避免使用multi-keys操作,比如mset/mget. multi-key操作有些用戶端沒有支援實現。
2.2 長時間阻塞引起的不必要的failover
  • 阻塞的命令。比如save/flushall/flushdb
  • 慢查詢。keys *、大key的操作、O(N)操作
  • rename危險操作:
    • rename-command FLUSHDB REDIS_FLUSHDB
    • rename-command FLUSHALL REDIS_FLUSHALL
    • rename-command KEYS REDIS_KEYS
2.3 同時支援ipv4和ipv6偵聽服務埋下的坑

具體現象:redis啟動正常,節點的協議連接埠只有ipv6 socket建立正常。異常節點也無法加入到叢集中,也無法擷取epoch。
解決方案:啟動時指定網卡ipv4地址,也可以是0.0.0.0,設定檔中添加:bind 0.0.0.0
這個是在setup叢集的時候發生過的一個問題,bind 0.0.0.0雖然存在一些安全性問題,但是是比較簡單通用的解決方案。

2.4 資料移轉速度較慢
  • 主要使用的redis-trib.rb reshard來完成資料移轉。
  • redis-3.0.6版本以前migrate操作是單個key逐一操作。從redis-3.0.6開始,支援單次遷移多個key。
  • redis叢集內部最多隻允許一個slot處於遷移狀態,不能並發的遷移slots。
  • redis-trib.rb reshard如果執行中斷,用redis-trib.rb fix修複叢集狀態。
2.5 版本選擇/升級建議
  • 我們已經開始使用3.0.7版本,很多3.2.0修複的bug已經backport到這個版本。
  • 另外我們也開始測試3.2.0版本,記憶體空間最佳化很大。
  • Tips
    • redis-trib.rb支援resharding/rebalance,分配權重。
    • redis-trib.rb支援從單個redis遷移資料到cluster叢集中。

後面2點不算坑把,算是不足,tips也很實用.開始分享下最佳實務。

3、最佳實務3.1 應用做好容錯機制
  • 串連或者請求異常,進行串連retry和reconnect。
  • 重試時間應該大於cluster-node-time時間
    還是強調容錯,這個不是針對cluster,所有的應用設計都適用。
3.2 制定開發規範
  • 慢查詢,進程cpu 100%、用戶端請求變慢,甚至逾時。
  • 避免產生hot-key,導致節點成為系統的短板。
  • 避免產生big-key,導致網卡打爆、慢查詢。
  • TTL, 設定合理的ttl,釋放記憶體。避免大量key在同一時間段到期,雖然redis已經做了很多最佳化,仍然會導致請求變慢。
  • key命名規則。
  • 避免使用阻塞操作,不建議使用事務。
    開發規範,使你們的開發按照最優的方式使用nosql。
3.3 最佳化串連池使用
  • 主要避免server端維持大量的串連。
  • 合理的串連池大小。
  • 合理的心跳檢測時間。
  • 快速釋放使用完的串連。
  • Jedis一個串連建立異常問題(fixed):
    https://github.com/xetorthio/jedis/issues/1252

串連問題是redis開發使用中最常見的問題,connection timeout/read timeout,還有borrow connection的問題。

3.4 區分redis/twemproxy和cluster的使用
  • redis建議使用pipeline和multi-keys操作,減少RTT次數,提高請求效率。
  • twemproxy也支援pipeline, 支援部分的multi-key可以操作。
  • redis cluster不建議使用pipeline和multi-keys操作,減少max redirect產生的情境。

區分redis 和 cluster的使用,一方面是資料分區引起的;另一方面,與client的實現支援相關。

3.5 幾個需要調整的參數

1)設定系統參數vm.overcommit_memory=1,可以避免bgsave/aofrewrite失敗。
2)設定timeout值大於0,可以使redis主動釋放空閑串連。
3)設定repl-backlog-size 64mb。預設值是1M,當寫入量很大時,backlog溢出會導致差異複寫不成功。
4)client buffer參數調整
client-output-buffer-limit normal 256mb 128mb 60
client-output-buffer-limit slave 512mb 256mb 180

四、營運經驗總結1、自動化管理
  • CMDB管理所有的資源資訊。
  • Agent方式上報硬軟體資訊。
  • 標準化基礎設定。機型、OS核心參數、軟體版本。
  • Puppet管理和下發標準化的設定檔、公用的任務計劃、軟體包、營運工具。
  • 資源申請自助服務。
2、自動化監控
  • zabbix作為主要的監控資料收集工具。
  • 開發即時效能dashboard,對開發提供查詢。
  • 單機部署多個redis,藉助於zabbix discovery。
  • 開發DB回應時間監控工具Titan。
  • 基本思想來源於pt-query-degest,通過分析tcp應答報文產生日誌。flume agent + kafka收集,spark即時計算,hbase作為儲存。最終得到hotquery/slowquery,request source等效能資料。
3、自動化營運
  • 資源申請自助服務化。
  • 如果申請合理,一鍵即可完成cluster叢集部署。
    能不動手的,就堅決不動手,另外,監控資料對開發開發很重要,讓他們瞭解自己服務效能,有時候開發會更早發現叢集的一些異常行為,比如資料不到期這種問題,營運就講這麼多了,後面是乾貨中的乾貨,由deep同學開發的幾個工具 + 生產力。
4、redis開源工具介紹4.1 redis即時資料遷移工具

1) 線上即時移轉
2) redis/twemproxy/cluster 異構叢集之間相互遷移。
3)github:https://github.com/vipshop/redis-migrate-tool

4.2 redis cluster管理工具

1)批量更改叢集參數
2)clusterrebalance
3)很多功能,具體看github :
https://github.com/deep011/redis-cluster-tool

4.3 多線程版本Twemproxy

1)大幅度提升單個proxy的輸送量,線程數可配置。
2)壓測情況下,20線程達到50w+qps,最優6線程達到29w。
3)完全相容twemproxy。
4)github:
https://github.com/vipshop/twemproxies

4.4 在開發的中的多線redis

1)Github:
https://github.com/vipshop/vire

2)歡迎一起參與協作開發,這是我們在開發中的項目,希望大家能夠提出好的意見。

問答(陳群和申政解答):問題1:版本更新,對資料有沒有影響?

答:我們重啟升級從2.8.17到3.0.3/3.0.7沒有任何的異常。3.0到3.2我們目前還沒有實際升級操作過。

問題2:請問下sentinel模式下有什麼好的讀寫分離的方法嗎

答:我們沒有讀寫分離的使用,讀寫都在maste;叢集太多,管理複雜;此外,我們也做了分區,沒有做讀寫分離的必要;且我們幾乎是一主一從節點配置

問題3:redis的fork主要是為了rdb吧,去掉是為了什麼呢

答:fork不友好

問題4:如果不用fork,是怎麼保證rdb快照是精確的,有其他cow機制麼

答:可以通過其他方法,這個還在探究階段,但目標是不用fork

問題5:就是redis cluster模式下大量操作會有很多問題,可是不大量操作又會降低業務系統的效能

答:確實存在這方面的問題,這方面支援需要用戶端的支援,但是jedis的作者也不大願意支援pipeline或者一些multi key操作。如果是大批量的操作,可以用多線程提高用戶端的輸送量。
(Redis中國使用者組著作權,轉載請註明來源)

附錄:

嘉賓:qunchenmy
技術部落格:[http://mdba.cn]
微博:[http://weibo.com/sylarqun]
Redis中國使用者組官網:[http://redis.cn]
Redis中國使用者組官方微博@redis2016
Redis知識圖譜:
[http://lib.csdn.net/base/redis]
[http://lib.csdn.net/mobile/base/34]
群二維碼:



文/Redis中國使用者組(簡書作者)
原文連結:http://www.jianshu.com/p/ee2aa7fe341b
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。

redis叢集討論

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.