您好,登錄后才能下訂單哦!
摘要:Redis Cluster作為最熱門的開源分布式緩存,在券商領域會有怎樣的應用場景?本文從華泰證券的應用現狀出發,介紹了Redis Cluster在華泰證券的大規模實踐經驗。
一、引言
Redis是一個開源(BSD許可)的內存Key-Value存儲系統,它可以用作數據庫、緩存和消息中間件。它支持多種類型的數據結構,如:字符串、散列)、列表、集合、有序集合與范圍查詢等。 Redis內置了復制、LRU驅動事件、事務、磁盤持久化等特性,并通過Redis哨兵(主從模式)和自動分區(Redis Cluster模式)提供高可用性。
官方的Redis Cluster推出前,常見的Redis Cluster開源方案主要是Codis和Twemproxy,兩者均采用Proxy的方式實現分布式。通過引入Proxy層來屏蔽底層數據的分布,可以簡化客戶端的實現,但使得集群架構變得復雜,維護成本上升。Redis從3.0開始支持自動分區,采用無中心節點方式實現Cluster模式。訪問Redis Cluster時,無需Proxy代理,具備Smart特性的客戶端直接與Redis Cluster中的每個節點連接。
Redis引入Cluster模式帶來的優勢在于:
1.可靠性:具有分區機制、副本機制和自動容錯機制;
2.高性能:保證了Redis高吞吐的前提下,可線性擴展到上千個節點;
3.可擴展性:基于分區的自動擴容、縮容,客戶端透明的數據遷移。
目前,Redis在互聯網、金融、傳統行業內的應用已十分廣泛。隨著金融業接入互聯網的業務增加,活動、促銷、節假日、熱門事件等可能帶來突發數倍甚至幾十倍的訪問峰值的情況時有發生,Redis Cluster是抵御突發海量訪問的有效手段。
2. 基本原理及概念
Redis Cluster整體設計是比較簡單的,集群架構采用無中心節點的方式實現,集群中的節點通過Gossip協議相互交換集群狀態。客戶端無需代理直接訪問服務端,客戶端通過Hash算法計算出Key對應的哈希槽,然后直接訪問哈希槽對應的服務端節點。
Redis Cluster的拓撲結構如下圖所示:
圖1 Redis Cluster架構圖
集群構建:
Redis Cluster提供了一組集群搭建和管理命令,如:CLUSTER INFO、CLUSTER NODES、CLUSTER MEET等。實際使用過程中可以借助命令行工具redis-trib.rb,可以方便的搭建一個集群、平衡集群哈希槽分布、刪除添加節點等。
搭建一個Redis Cluster僅需兩步:1.節點準備,將編譯好的Redis發布到至少三臺服務器上,修改配置文件并啟動Redis節點;2.節點握手,使用redis-tribcreate host1:port1 … hostN:portN命令完成節點握手并確認槽位分配。服務器上有多個Redis實例時,注意修改服務的端口、工作目錄、AOF和RDB文件名等配置。創建集群時可以指定副本數,也可以在集群創建完成后,將從節點逐個添加到集群中去。
數據分布:
Redis Cluster基于哈希槽(分片)的方式將數據分布到16384個槽中,每個Master節點負責一部分哈希槽的數據存儲。Redis中的每個鍵都會被映射到這些哈希槽的其中一個,集群使用Hash公式CRC16(key)%16384來計算鍵key屬于哪個槽。
Redis的Smart客戶端在訪問集群時,先獲取并緩存哈希槽和節點的映射關系,然后通過計算Key對應的哈希槽編號查找應該訪問的節點。為了配合集群擴縮容、數據遷移等哈希槽映射需要改變的操作,Redis服務端添加了MOVED、ASK兩種響應策略,前者通知客戶端所訪問的哈希槽所在的新節點,后者則通知客戶端哈希槽正在遷移到哪個節點。
主從復制:
Redis Cluster節點間使用異步冗余備份(Asynchronous Replication),不能保證數據的強一致性。可能出現數據丟失的場景:修改操作完成主節點上更新,當主節點回復客戶端成功后,增量改動未能同步到從節點,此時主節點異常(宕機、故障轉移等),從節點成為主節點;客戶端路由表更新窗口期間,集群內或許會有主從角色快速出現兩次切換,此時數據仍有可能寫錯節點,最終造成數據丟失。
雖然Redis主從復制不能保證強一致性,但在不出現主從切換的情況下,數據出現不一致的情況還是很難出現的。實際生產環境下,出現主從切換的概率不大,但仍建議業務系統要有容忍緩存數據丟失的能力。
故障檢測:
Redis Cluster中的每個節點都存儲有一份其他已知節點的標識列表,其中有兩個標識是用于失效檢測,分別是 PFAIL 和 FAIL。當一個節點在超過NODE_TIMEOUT時間后仍無法訪問某個節點,他會將被檢測節點標識為PFAIL,表示可能失效;一個節點被大多數主節點確認不可達,則會標識為FAIL,表示已經失效。
每個節點定時向其他節點發送Gossip消息,消息中包含一些隨機的已知節點的狀態。最終每個節點都能收到一份其他節點的標識。當節點被標記為FAIL時,就需要提升一個從節點來做主節點。
故障轉移:
當一個負責槽位數大于0的主節點處于FAIL狀態時,他的從節點可以自動的發起選舉。一旦某個從節點收到了大多數主節點的回應,那么它將提升為新的主節點。另外,Redis Cluster提供了手動故障遷移的命令CLUSTER FAILOVER,可以在運維使用。
3. Redis Cluster在華泰證券背景介紹及建設現狀
2015年,隨著華泰證券互聯網金融自主研發的大規模投入,面對海量用戶并發場景,迫切需要建設統一化、服務化的分布式緩存平臺。
通過對Redis Cluster、Codis及Twemproxy等開源Redis集群解決方案進行驗證和對比,最終從性能、易維護、高可用等方面考慮,選擇Redis 3.2.0版本的Cluster模式作為公司級緩存解決方案。Redis Cluster獲得了開源社區的持續支持,功能、特性一直在迭代改進。相比之下,Codis及Twemproxy社區活躍度較低,維護成本相對較高,吞吐量也略遜于Redis Cluster。
目前,在華泰證券建設有多套Redis Cluster資源池,總體集群服務器數量20余臺。在交易時段,峰值訪問量超20萬次/秒,服務了30個以上應用系統,包括:行情中心、漲樂財富通、互聯網用戶中心等,在緩存、分布式鎖、內存存儲、任務隊列等業務場景都有應用。
4. 實踐經驗
(1)高可用多活架構
如圖2所示,Redis Cluster數據節點采用同城三數據中心部署方式,通常其中兩個數據中心部署數量相等的機器,另一數據中心部署單臺機器。為加速重做從節點的速度,主機采用萬兆網卡。為保證訪問緩存的延時足夠小,跨數據中心之間的網絡通信采用獨立的萬兆波分通道。
實際部署時,需要調整Redis Cluster的Master節點分布,要保證任意一個數據中心Master節點數小于集群的一半。采取這樣的部署架構,如果單數據中心出現問題,另一個中心能自動進行接管,業務系統可以無感知切換。
(2)Java客戶端層面的調優
1、推薦使用Jedis2.8.x及以上版本,關閉TestOnReturn和TestOnBorrow;
2、推薦使用Jedis的JedisPoolConfig,它是對GenericObjectPoolConfig的優化版本;
3、合理使用HGETALL、SMEMBERS等O(N)操作。
(3)服務端層面的優化
1、重命名KEYS、FLUSHALL、FLUSHDB等耗時且危險的操作;
2、適度加大client-output-buffer-limitslave避免不必要的重做從節點;
3、適度加大repl-backlog-size和repl-backlog-ttl,值越大slave可丟失的時間越長;
4、AOF,關閉RDB,減少服務端fork操作造成的訪問出現卡頓的現象;
5、根據實際場景配置cluster-require-full-coverage為yes,減少集群不可用的時間。
(4)Redis Cluster的功能限制
Redis cluster是分布式的Redis實現,具有一定的容錯性和線性可擴展性,這些特性犧牲了以下功能:
1、不能使用SELECT命令,不支持對多個槽位內的KEY進行操作,比如MSET、SUNION;
2、發布訂閱功能不推薦使用,集群規模越大,產生的網絡流量越大;
3、采用Redis主從模式的應用,客戶端代碼需要少量的改造才能升級到Cluster模式。
(5)問題跟進及版本更新
開源中間件難免出現Bug及其它性能問題,大部分問題開源社區都能找到問題的解決方案,積極的跟進社區討論是有效的避免生產事故的有效途徑。在實際使用中,我們發現了多個Redis的Bug,社區均有解決方案。目前,我們已經將生產環境上部分Redis節點升級到3.2.7版本,主要因為遇到以下問題:
1、從節點同步Ziplist后,List索引更新錯誤,造成從節點Crash;
2、Ziplist中成員長度增長,List索引更新錯誤,造成主節點和從節點的AOF重寫均失敗,產生大量臨時文件。
(6)持續跟進
Redis 2.8.0版本開始引入PSYNC機制,PSYNC通過添加緩沖隊列,緩存從節點斷開連接期間的數據變化增量,當從節點重新連接且緩存隊列未溢出時,則可避免早期版本從節點重連后必然需要SYNC操作全量同步主節點數據的問題。
PSYNC可以有效地解決網絡抖動造成的從節點短暫斷開連接的問題,但無法避免當主節點、從節點相繼出現網絡失連、重啟、進程推出的情況發生后的全量數據同步和恢復,Redis 4.0引入PSYNC 2和PSYNC 3等新特性來解決相關問題。目前Redis 4.0仍處于驗證階段,需要持續驗證和密切關注。
5.典型場景
與其它開源的key-value內存存儲系統相比,Redis支持的數據更加豐富,常用的value數據類型包括:字符串、哈希表、鏈表、集合、有序集合。同時,Redis還內置了這些數據結構的常見操作。目前,Redis的應用已經非常廣泛,常見的使用場景包括:緩存熱數據、計數器、隊列、分布式鎖、排行榜、新聞列表、評論等場景。Redis Cluster在華泰證券的新建信息系統中也得到了廣泛的應用,使用的部分場景舉例如下:
行情截面
某些應用場景可能需要獲取某個市場或多個股票的最新行情,可以使用Redis的Hash結構來實現這個需求。示例代碼如下:
添加或更新一只股票的行情
HSETMD:XSHG:STOCKTYPE “601688.SH” 17.88
獲取多只股票最新行情
HMGET MD:XSHG:STOCKTYPE “601688.SH” “601689.SH”
獲取某個交易所所以股票最新行情,HGETALL操作為O(N)操作,不建議頻繁調用
HGETALL MD:XSHG:STOCKTYPE
K線
常見的K線為日K線或分鐘K線,以日K線為例,可以使用Redis的有序集合來實現,示例代碼如下:
添加某只股票2018年3月1的K線
ZADD KLINE:1DAY:601688.SH 20180301 kline_value
獲取某只股票多天的K線
ZRANGEBYSCORE KLINE:1DAY:601688.SH 20180301 20180302
任務隊列
任務隊列用來在任務的生產者和消費者之間傳遞任務,實現任務的產生和任務執行模塊間的松耦合。實例代碼如下:
生產者生成一個任務task01
RPUSH TASK:QUEUE “task01”
消費者堵塞等待100秒等待任務,BLPOP是LPOP的堵塞版本
BLPOP TASK:QUEUE 100
6.未來規劃
隨著業務的不斷發展,Redis Cluster在華泰證券內部已成為核心組件。未來重點進行PaaS平臺建設,加強集群自動化災備;建立分級保障制度,對重點業務進行獨立管理。目前,Redis的最新版本4.0.x解決了Redis 3.2.x版本在面對網絡劇烈抖動時,偶爾會出現部分分片所在的主從節點均不可用的情況。盡早驗證Redis 4.0.x版本的穩定性,制定有效的升級方案和計劃,也將是未來工作的重點之一。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。