標籤:blog http io os 使用 java ar strong 資料
簡單說明下,寫此文章算是對自己近一段工作的總結,希望能對你有點協助,同時也是自己的一點小積累。
一.為什麼選擇redis
在項目中使用redis做為緩衝,還沒有使用memcache,考慮因素主要有兩點:
1.redis豐富的資料結構,其hash,list,set以及功能豐富的String的支援,對於實際項目中的使用有很大的幫忙。(可參考官網redis.io)
2.redis單點的效能也非常高效(利用項目中的資料測試優於memcache).
基於以上考慮,因此選用了redis來做為緩衝應用。
二.分布式緩衝的架構設計
1.架構設計
由於redis是單點,項目中需要使用,必須自己實現分布式。基本架構圖如下所示:
2.分布式實現
通過key做一致性雜湊,實現key對應redis結點的分布。
一致性雜湊的實現:
l hash值計算:通過支援MD5與MurmurHash兩種計算方式,預設是採用MurmurHash,高效的hash計算。
l 一致性的實現:通過java的TreeMap來類比環狀結構,實現均勻分布
3.client的選擇
對於jedis修改的主要是分區模組的修改,使其支援了跟據BufferKey進行分區,跟據不同的redis結點資訊,可以初始化不同的ShardInfo,同時也修改了JedisPool的底層實現,使其串連pool池支援跟據key,value的構造方法,跟據不同ShardInfos,建立不同的jedis串連用戶端,達到分區的效果,供應用程式層調用
4.模組的說明
l 髒資料處理模組,處理失敗執行的快取作業。
l 屏蔽監控模組,對於jedis操作的異常監控,當某結點出現異常可控制redis結點的切除等操作。
整個分布式模組通過hornetq,來切除異常redis結點。對於新結點的增加,也可以通過reload方法實現增加。(此模組對於新增結點也可以很方便實現)
對於以上分布式架構的實現滿足了項目的需求。另外使用中對於一些比較重要用途的快取資料可以單獨設定一些redis結點,設定特定的優先順序。另外對於緩衝介面的設計,也可以跟據需求,實現基本介面與一些特殊邏輯介面。對於cas相關操作,以及一些事物操作可以通過其watch機制來實現。(參考我以前寫的redis事物介紹)
以上是基於redis分布式架構的介紹!但是應用中讀寫都是在一起的。相關寫是在應用操作後flush或者update的,有一定的耦合。為了使讀寫分離,以及緩衝模組跟應用的耦合更小,考慮使用mysql binlog來重新整理緩衝。以下是基於binlog重新整理可性行分析以及實現過程中需要注意的地方。
三.採用binlog架構重新整理緩衝可行性分析
1.Mysql日誌格式介紹可參考我以前的的介紹。
2.對於使用MIXED日誌格式,此日誌格式,記錄的是對應資料庫操作的SQL語句,採用此日誌方式存在的問題:
l 對於一些未任何更新操作的SQl語句,像條件不滿足,對應的sql也會記錄到binlog日誌中。
l SQL語句記錄的未必包括所有的更新操作。
l 對於一些分散式資料庫,對於SQL中的where條件指定的是非均衡欄位,也許會存在多條SQL,跟設計有關!
基於以上考慮,採用MIXED的日誌格式進行binlog解析是行不通的。(官網給出的指示是failed statementsare not logged ,但不包括文法沒錯誤,更新條件不符合對應的SQL)
3.採用ROW日誌格式
對於此日誌格式,每行變化都有對應的記錄,此日誌格式,對於解析及採集資料都是非常方便的,也只有採用此日誌格式,才能基於binlog修改,做重新整理緩衝相關方案的設計。但是基於此日誌格式也存在一些問題:
l 需要考慮項目中是否有大量的批量的update操作,如果採用此日誌格式,大量操作每一行修改都會記錄一條日誌,大量的大量操作所產生的日誌量,以及所帶來的IO開銷是否可以接受。
通過以上分析,最終項目中還是考慮基於ROW日誌格式進行緩衝重新整理,還有一個問題需要考慮,在應用程式層DB進行了相應的update操作後,所產生的Binlog是會帶來一定的延遲,如果Binlog處理模組正常運行,資料是的延遲會非常少,MS層級以內,對使用者體驗是沒有感知的,但是Binlog模組是多點,異常,以及相應的延遲肯定會是存在的,這樣,快取資料肯定會存在髒資料。
不過通過以上方案,資料能達到最終一致性,因此how to權衡,需要考慮。
通過以上分析,是否採用Binlog來做快取資料重新整理相信大家有一個基本概念了
四.基於binlog重新整理緩衝的實現時注意的地方
1.如果是採用java做相關開發,可以使用開源的tungstenAPI
2.Binlog日誌解析是按照mysql 的master/slave同步流程來實現,即一個線程同步,一個線程解析。
3.設計是可分Binlog處理模組以及緩衝處理SqlEvent兩部分,其中Binlog處理解析好對應的SqlEvent,然後對應的緩衝重新整理處理SqlEvent,一個簡單的生產者-消費者模式。
4.對於多個Binlog處理模組可以是單點,也可以是通過一些協同工具來管理,看需求。可以使用ZooKeeper等。
5.對於分布式緩衝中的資料,對於Binlog來重新整理的快取資料會存在load資料的問題,為了減輕DB的額外壓力,flush操作可在get快取資料處完成。看需求,如果讀寫完全分享的話此DB的額外壓力可以接收的話也可行。
6.對於快取資料性一致性要求比較高的,可以通過版本號碼來控制,即在應用程式層引入一定的耦合,在DB操作時帶mark ,緩衝重新整理是也mark,另外get操作時比較雙版本號碼來達到資料的一致性。(此跟5談論的一定的聯絡,讀寫是否完全分離,以及相應一致性實現的一些方法)
五.一點心得
前前後後,對redis完成調研,以及相關的一些使用,分布式緩衝的實現,基於binlog方式的修改等,接觸有一年多了,這段時間下來,學了很多,以上算是一點小記,這部分工作的一點小記。實現過程中存在更多的問題。
對於調研相關的一些工作,一定要做的仔細,相應的細節一定要瞭解透徹,否則也許一此小問題會導致整個方案的不可行,甚至更大的的問題。連鎖反應!
接下來有時間會寫一篇關於BloomFilter的的文章 ,以及D-Left_BloomFilter,在此說明,只為自己有更大的動力去完成它。項目中實現了D-Left_BloomFilter,但在網上沒有相關實現,在對其最佳化後,會在博文上做一些小小的記錄。
轉載自haier_jiang的專欄基於redis分布式緩衝實現