唯品會大規模 Redis Cluster 的生産實踐

1、生産應用場景

 

1.1 業務範圍

 

        redis cluster在唯品會主要應用于後端業務,用作內存存儲服務。主要大數據實時推薦/ETL、風控、營銷三大業使用。

        cluster用于取代當前twemproxy三層架構,作爲通用的存儲架構。redis cluster可以大幅度簡化我們的存儲架構,也解決twemproxy架構無法在線擴容節點的問題。

        目前我們在線有生産幾十個cluster集群,約2千個instances,單個集群最大達到250+instances。

        這是我們的生産應用場景,主要是後端業務的存儲,目前沒有作爲cache使用的場景。

 

1.2大數據、風控、營銷系統的特征

 

         cluster 壹般數據量大, 單個cluster集群在幾十個GB到上TB級別內存存儲量。

          作爲後端應用的存儲,數據來源主要以下三種方式:

 

(1)Kafka → Redis Cluster,Storm/Spark實時

(2)Hive →  Redis Cluster,  MapReduce程序

(3)MySQL →  Redis Cluster,Java/C++程序。

 

        數據由離線/實時job生成, 讀寫請求量大, 對讀寫性能也要求高。

 

        業務高峰期請求量急劇上升,幾倍的讀寫量增加,需要多個redis實例承擔業務的讀寫壓力。

        業務需求變化快, schema變化頻繁。如果使用MySQL作爲存儲,那麽將會是頻繁的DLL變更,而且需要做online schema change。

        大促銷活動時擴容頻繁。

 

1.3、爲什麽選擇redis cluster

 

1) cluster適合我們後端生産應用場景

 

        a、在線水平擴展能力,能夠解決我們大量的擴容需求。

        b、Failover能力和高可用性。

        c、雖然cluster不保證主從數據強壹致性,但是後端業務能夠容忍failover後少量的數據丟失。

 

2) 架構簡單

 

        a、無中心架構,各個節點度等。slave節點提供數據冗余,master節點異常時提升爲master。

        b、取代twemproxy三層架構,系統複雜性降低。

        c、可以節約大量的硬件資源,我們的Lvs + Twemproxy層 使用了近上千台物理機器。

        d、少了lvs和twemproxy層,讀寫性能提升明顯。響應時間從100-200us減少到50-100us。

       e、系統瓶頸更少。lvs層網卡和pps吞吐量瓶頸;對于請求長度較大的業務,twemproxy單節點性能低。

 

        總結下,我們選擇redis cluster主要這兩點原因:簡單、擴展性。另外,我們用cluster取代twemproxy集群,三層架構實在是很令人頭疼,複雜、瓶頸多、管理不方面。

 

2、存儲架構演變

 

2.1 架構演變

 

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1

 

      在2014年7月,爲了准備當時的814撒嬌節大促銷活動,我們把單個redis的服務遷移到twemproxy上。twemproxy在後端快速完成數據分片和擴容。爲了避免再次擴容,我們靜態分配足夠多的資源。

 

        之後,twemproxy暴露出來的系統瓶頸很多,資源使用很多,也存在壹定的浪費。我們決定用redis cluster取代這種複雜的三層架構。

 

        redis cluster GA之後,我們就開始上線使用。最初是3.0.2 版本,後面大量使用3.0.3 ,上個月開始使用3.0.7版本。

 

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

 

2.2 Twemproxy架構

 

1)優點

 

a、sharding邏輯對開發透明,讀寫方式和單個redis壹致。

b、可以作爲cache和storage的proxy(by auto-eject)。

 

2)缺點

 

a、架構複雜,層次多。包括lvs、twemproxy、redis、sentinel和其控制層程序。

b、管理成本和硬件成本很高。

c、2 * 1Gbps 網卡的lvs機器,最大能支撐140萬pps。

d、流量高的系統,proxy節點數和redis個數接近。

e、Redis層仍然擴容能力差,預分配足夠的redis存儲節點。

 

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1

 

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

 

2.3 Redis Cluster架構

 

1)優點

 

a、無中心架構。

b、數據按照slot存儲分布在多個redis實例上。

c、增加slave做standby數據副本,用于failover,使集群快速恢複。

d、實現故障auto failover。節點之間通過gossip協議交換狀態信息;投票機制         完成slave到master角色的提升。

e、亦可manual failover,爲升級和遷移提供可操作方案。

f、降低硬件成本和運維成本,提高系統的擴展性和可用性。

 

2)缺點

 

a、client實現複雜,驅動要求實現smart client,緩存slots mapping信息並及時      更新。

b、目前僅JedisCluster相對成熟,異常處理部分還不完善,比如常見的“max re       direct exception”。

c、客戶端的不成熟,影響應用的穩定性,提高開發難度。

d、節點會因爲某些原因發生阻塞(阻塞時間大于clutser-node-timeout),被判斷下線。這種failover是沒有必要,sentinel也存在這種切換場景。

 

cluster的架構如下:

 

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1

 

 

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

 

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

 

3、應用最佳實踐

 

本部分包括內容如下:

 

a、redis cluster的穩定性如何?

b、存在哪些坑?

c、develop guideline & best practice

 

3.1 穩定性

 

a、不擴容時集群非常穩定。

b、擴容resharding時候,早期版本的Jedis端有時會出現“max-redirect”異常。

      分析Jedis源碼,請求重試次數達到了上限,仍然沒有請求成功。兩方面分         析:redis連接不上?還是集群節點信息不壹致?

c、存活檢測機制缺陷

     redis 存活檢測機制可能因爲master 節點上慢查詢、阻塞式命令、或者其它        的性能問題導致長時間沒有響應,這個節點會認爲處于failed狀態,並進行        切換。這種切換是沒必要的。

 

優化策略:

 

a) 默認的cluster-node-timeout爲15s,可以適當增大;

 

b) 避免使用會引起長時間阻塞的命令,比如save/flushdb等阻塞操作,或者keys pattern這種慢查詢。

 

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

 

3.2 有哪些坑?

 

1)遷移過程中Jedis“Max Redirect”異常。

 

a、github上討論的結果是程序retry。

b、max redirt issues:https://github.com/xetorthio/jedis/issues/1238

c、retry時間應該大于failover 時間。

d、Jedis參數優化調整:增大jedis中的‘DEFAULT_MAX_REDIRECTIONS’參           數,默認值是5.

e、避免使用multi-keys操作,比如mset/mget. multi-key操作有些客戶端沒有支      持實現。

 

2)長時間阻塞引起的不必要的failover

 

a、阻塞的命令。比如save/flushall/flushdb

b、慢查詢。keys *、大key的操作、O(N)操作

c、rename危險操作:

     · rename-command FLUSHDB REDIS_FLUSHDB

     · rename-command FLUSHALL REDIS_FLUSHALL

     · rename-command KEYS REDIS_KEYS

 

3)同時支持ipv4和ipv6偵聽服務埋下的坑

 

        具體現象:redis啓動正常,節點的協議端口只有ipv6 socket創建正常。異常節點也無法加入到集群中,也無法獲取epoch。

 

        解決方法:啓動時指定網卡ipv4地址,也可以是0.0.0.0,配置文件中添加:bind 0.0.0.0

 

        這個是在setup集群的時候發生過的壹個問題,bind 0.0.0.0雖然存在壹些安全性問題,但是是比較簡單通用的解決方法。

 

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修複集群狀態。

 

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也很實用。開始分享下最佳實踐。

 

4、最佳實踐

 

4.1 應用做好容錯機制

 

· 連接或者請求異常,進行連接retry和reconnect。

· 重試時間應該大于cluster-node-time時間. 

     

       還是強調容錯,這個不是針對cluster,所有的應用設計都適用。

 

4.2 制定開發規範

 

· 慢查詢,進程cpu 100%、客戶端請求變慢,甚至超時。

· 避免産生hot-key,導致節點成爲系統的短板。

· 避免産生big-key,導致網卡打爆、慢查詢。

· TTL, 設置合理的ttl,釋放內存。避免大量key在同壹時間段過期,雖然redis已· 經做了很多優化,仍然會導致請求變慢。

· key命名規則。

· 避免使用阻塞操作,不建議使用事務。

· 開發規範,使妳們的開發按照最優的方式使用nosql。

 

4.3 優化連接池使用

 

· 主要避免server端維持大量的連接。

· 合理的連接池大小。

· 合理的心跳檢測時間。

· 快速釋放使用完的連接。

· Jedis壹個連接創建異常問題(fixed):

· https://github.com/xetorthio/jedis/issues/1252  

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

 

4.4 區分redis/twemproxy和cluster的使用

 

· redis建議使用pipeline和multi-keys操作,減少RTT次數,提高請求效率。

· twemproxy也支持pipeline, 支持部分的multi-key可以操作。

· redis cluster不建議使用pipeline和multi-keys操作,減少max redirect産生的場景。

· 區分redis 和 cluster的使用,壹方面是數據分片引起的;另壹方面,與client的實現支持相關。

 

4.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

 

5、運維經驗總結

 

5.1 自動化管理

 

· CMDB管理所有的資源信息。

· Agent方式上報硬軟件信息。

· 標准化基礎設置。機型、OS內核參數、軟件版本。

· Puppet管理和下發標准化的配置文件、公用的任務計劃、軟件包、運維工具。

· 資源申請自助服務。

 

5.2 自動化監控

 

· zabbix作爲主要的監控數據收集工具。

· 開發實時性能dashboard,對開發提供查詢。

· 單機部署多個redis,借助于zabbix discovery。

· 開發DB響應時間監控工具Titan。

· 基本思想來源于pt-query-degest,通過分析tcp應答報文産生日志。flume agent + kafka收集,spark實時計算,hbase作爲存儲。最終得到hotquery/slowquery,request source等性能數據。

 

5.3 自動化運維

 

· 資源申請自助服務化。

· 如果申請合理,壹鍵即可完成cluster集群部署。

  能不動手的,就堅決不動手,另外,監控數據對開發開發很重要,讓他們了解自己服務性能,有時候開發會更早發現集群的壹些異常行爲,比如數據不過期這種問題,運維就講這麽多了,後面是幹貨中的幹貨,由deep同學開發的幾個實用工具。

 

5.4 redis開源工具介紹

 

 redis實時數據遷移工具

 

1)在線實時遷移

2)redis/twemproxy/cluster 異構集群之間相互遷移。

3)github:https://github.com/vipshop/redis-migrate-tool 

 

redis cluster管理工具

 

1)批量更改集群參數

2)clusterrebalance

3)很多功能,具體看github :

https://github.com/deep011/redis-cluster-tool

 

多線程版本Twemproxy

 

1)大幅度提升單個proxy的吞吐量,線程數可配置。

2)壓測情況下,20線程達到50w+qps,最優6線程達到29w。

3)完全兼容twemproxy。

4)github:

https://github.com/vipshop/twemproxies

 

在開發的中的多線redis

 

1)Github:

https://github.com/vipshop/vire

(本文为连刊,预知菜鸟的逆袭,请继续关注,直接扫描以下二维码并关注,便可查阅菜鸟逆袭全刊!加入我们,摇身一变“高富帅”“白富美”,掌握好技术,拿高薪、买房买车!走向人生巅峰!!!快来吧!!!)

 

由于上传附件及文字限制,有时部分图片、文字可能显示不了,详情请见:http://mp.weixin.qq.com/s?__biz=MzI5ODI3NzY2MA==&mid=100000731&idx=2&sn=5951fb3d54b70790240c97056c05112f#rd
欢迎大家一起交流。
扫描以下二维码,获取更多更精美文章!(扫码关注有意向不到的惊喜的哦!!)
 
关注我们微信订阅号( uniguytech100) 与服务号(uniguytech),获取更多更精美文章!
也欢迎加入【大家技术网讨论QQ群】,群号码:256175955,请备注你个人的介绍!让我们一起聊聊it的那些事!

转载于:https://my.oschina.net/uniguy/blog/686814

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值