Dynomite研究(Netflix數(shù)據(jù)庫(kù)同步工具)

1、概述

Dynomite是Netflix實(shí)現(xiàn)的一個(gè)Redis數(shù)據(jù)庫(kù)同步復(fù)制方案。其思路來(lái)自于亞馬遜的Dynamo的白皮書 Dynamo whitepaper。目前支持Redis和Memcached,Dynomite的最終目標(biāo)是能夠在存儲(chǔ)引擎上實(shí)現(xiàn)高效的,不復(fù)雜的高可用性和跨數(shù)據(jù)中心復(fù)制,即使存儲(chǔ)引擎本身不提供這種功能。

Dynomite有數(shù)據(jù)中心、機(jī)架、節(jié)點(diǎn)的三層概念,數(shù)據(jù)中心可以有多個(gè)機(jī)架,機(jī)架可以有多個(gè)節(jié)點(diǎn)。每個(gè)機(jī)架數(shù)據(jù)是完整的,機(jī)架上的不同節(jié)點(diǎn)各有一部分?jǐn)?shù)據(jù),即是數(shù)據(jù)分片。大體原理可以看下這個(gè)文章關(guān)于Dynomite的部分原理解釋。

2、安裝配置

2.1、編譯

可以通過以下步驟安裝所需工具,使用wget下載特定版本代碼并編譯,目前最新穩(wěn)定版l'l是v0.6

yum install -y git autoconf automake libtool openssl-devel net-tools
wget https://github.com/Netflix/dynomite/archive/v0.6.zip
unzip v0.6.zip 
cd dynomite-0.6
autoreconf -fvi
./configure --enable-debug=false
make
src/dynomite -h

在src目錄下的 dynomite 就是編譯結(jié)果

接著建立工作目錄,并移動(dòng)執(zhí)行程序到工作目錄下

mkdir -p /apps/dynomite/bin
mkdir -p /apps/dynomite/conf
cp src/dynomite /apps/dynomite/bin/

2.2、部署

為了方便測(cè)試,我在兩個(gè)云服務(wù)器A、B分別部署兩個(gè)Dynomite節(jié)點(diǎn),A1、A2、B1、B2共四個(gè)節(jié)點(diǎn)構(gòu)成集群。每個(gè)Dynomite代理一個(gè)Redis節(jié)點(diǎn),在Dynomite所在機(jī)器本機(jī)上啟動(dòng)對(duì)應(yīng)Redis即可。

也就是一個(gè)云服務(wù)器模擬一個(gè)數(shù)據(jù)中心,同一個(gè)云服務(wù)上的兩個(gè)Dynomite節(jié)點(diǎn)模擬同一個(gè)機(jī)架上的兩個(gè)節(jié)點(diǎn)。這樣就可以模擬一個(gè)雙數(shù)據(jù)中心集群,一個(gè)數(shù)據(jù)中心有一個(gè)機(jī)架,同機(jī)架的兩個(gè)節(jié)點(diǎn)按數(shù)據(jù)分片規(guī)則保存部分?jǐn)?shù)據(jù)。

首先每個(gè)服務(wù)器上起兩個(gè)redis實(shí)例,分別用6378、6379端口,并打開遠(yuǎn)程連接。打開遠(yuǎn)程主要是為了方便后面進(jìn)行非本機(jī)壓測(cè)性能對(duì)比,實(shí)際使用時(shí)如果Dynomite和Redis在同服務(wù)器可以不開。

6378配置文件redis6378_simple.conf

bind 改為對(duì)應(yīng)ip
protected-mode no
port 6378

6379配置redis6379_simple.conf

bind 改為對(duì)應(yīng)ip
protected-mode no
port 6379

然后使用指令啟動(dòng)兩個(gè)Redis實(shí)例

redis-server /etc/redis6378_simple.conf&
redis-server /etc/redis6379_simple.conf&

接著生成一個(gè)公鑰私鑰對(duì),用下面的指令在 conf目錄生成兩個(gè)秘鑰文件 dynomite.pem 和 dynomite.pem.pub,這兩個(gè)文件后面要寫到配置文件中。

ssh-keygen -t rsa -f conf/dynomite.pem

接著配置Dynomite節(jié)點(diǎn),其主要配置項(xiàng)意義如下

rack             機(jī)架號(hào)
dyn_listen        dynomite集群同步數(shù)據(jù)的監(jiān)聽地址和端口
dyn_seeds         集群中其他節(jié)點(diǎn)的信息
data_store        存儲(chǔ)類型  0 代表redis 1 代表memcached
listen            客戶端訪問數(shù)據(jù)的地址和端口
servers           本Dynomite節(jié)點(diǎn)對(duì)接的redis的ip,端口,權(quán)重。這個(gè)字段未來(lái)可能會(huì)支持列表的,即支持一個(gè)Dynomite節(jié)點(diǎn)對(duì)接多個(gè)Redis節(jié)點(diǎn)
tokens            可以認(rèn)為是集群中的唯一編碼,最好是按照一定規(guī)則區(qū)分編碼,避免重復(fù)
secure_server_option 通訊加密方案,可選值'none'、'rack'、'datacenter'、'all',none表示無(wú)加密,rack表示不同機(jī)架間通訊加密,datacenter表示不同數(shù)據(jù)中心間通訊加密,all表示全部通訊加密。
recon_key_file     公鑰文件
recon_iv_file      私鑰文件
max_msgs           緩存的最大消息數(shù),默認(rèn)200000,可以配置大點(diǎn)

將下面實(shí)例的Dynomite節(jié)點(diǎn)的配置文件保存到目錄/apps/dynomite/conf中。

A1對(duì)應(yīng)的dynomite配置

dyn_o_mite:
  datacenter: dc1
  rack: rack1
  dyn_listen: 192.168.1.1:8101
  dyn_seeds:
  - 192.168.1.1:8201:rack1:dc1:112
  - 192.168.1.2:8101:rack1:dc2:211
  - 192.168.1.2:8201:rack1:dc2:212
  data_store: 0
  listen: 192.168.1.1:8102
  dyn_seed_provider: simple_provider
  servers:
  - 192.168.1.1:6378:1
  tokens: 111
  secure_server_option: none
  stats_listen: 127.0.0.1:30001
  recon_key_file: conf/dynomite.pem.pub
  recon_iv_file: conf/dynomite.pem
  max_msgs: 500000

A2對(duì)應(yīng)的dynomite配置

dyn_o_mite:
  datacenter: dc1
  rack: rack1
  dyn_listen: 192.168.1.1:8201
  dyn_seeds:
  - 192.168.1.1:8101:rack1:dc1:111
  - 192.168.1.2:8101:rack1:dc2:211
  - 192.168.1.2:8201:rack1:dc2:212
  data_store: 0
  listen: 192.168.1.1:8202
  dyn_seed_provider: simple_provider
  servers:
  - 192.168.1.1:6379:1
  tokens: 112
  secure_server_option: none
  stats_listen: 127.0.0.1:30002
  recon_key_file: conf/dynomite.pem.pub
  recon_iv_file: conf/dynomite.pem  
  max_msgs: 500000  

B1對(duì)應(yīng)的dynomite配置

dyn_o_mite:
  datacenter: dc2
  rack: rack1
  dyn_listen: 192.168.1.2:8101
  dyn_seeds:
  - 192.168.1.2:8201:rack1:dc2:212
  - 192.168.1.1:8101:rack1:dc1:111
  - 192.168.1.1:8201:rack1:dc1:112
  data_store: 0
  listen: 192.168.1.2:8102
  dyn_seed_provider: simple_provider
  servers:
  - 192.168.1.2:6378:1
  tokens: 211
  secure_server_option: none
  stats_listen: 127.0.0.1:30001
  recon_key_file: conf/dynomite.pem.pub
  recon_iv_file: conf/dynomite.pem  
  max_msgs: 500000  

B2對(duì)應(yīng)的dynomite配置

dyn_o_mite:
  datacenter: dc2
  rack: rack1
  dyn_listen: 192.168.1.2:8201
  dyn_seeds:
  - 192.168.1.2:8101:rack1:dc2:211
  - 192.168.1.1:8101:rack1:dc1:111
  - 192.168.1.1:8201:rack1:dc1:112
  data_store: 0
  listen: 192.168.1.2:8202
  dyn_seed_provider: simple_provider
  servers:
  - 192.168.1.2:6379:1
  tokens: 212
  secure_server_option: none
  stats_listen: 127.0.0.1:30002 
  recon_key_file: conf/dynomite.pem.pub
  recon_iv_file: conf/dynomite.pem  
  max_msgs: 500000

然后使用使用以下指令分別啟動(dòng)dynomit節(jié)點(diǎn),-d 表示后臺(tái)運(yùn)行

./bin/dynomite -c conf/node1.yml -d --output=node1.log
./bin/dynomite -c conf/node2.yml -d --output=node2.log

接著使用redis-cli連接到dynomite的任一個(gè)節(jié)點(diǎn)進(jìn)行測(cè)試,會(huì)發(fā)現(xiàn)任意dynomite節(jié)點(diǎn)修改數(shù)據(jù)后另外一個(gè)dynomite實(shí)例都可以查到。注意keys * 、flushall、del key1 key2 等批量指令不能正常運(yùn)行。

redis-cli -h 更改為你的ip -p port

接著直接連接各個(gè)redis節(jié)點(diǎn)檢查數(shù)據(jù),會(huì)發(fā)現(xiàn)同一個(gè)數(shù)據(jù)中心的一個(gè)機(jī)架包含了完整數(shù)據(jù),而同一個(gè)機(jī)架中的節(jié)點(diǎn)的數(shù)據(jù)不重復(fù)。

redis-cli -h 更改為你的ip -p port

4、性能分析

4.1、Dynomite代理造成的性能損失

每個(gè)Dynomite節(jié)點(diǎn)都會(huì)作為一個(gè)Redis實(shí)例的代理,直接使用壓測(cè)工具 redis-benchmark 測(cè)試連接到Dynomite以及直連Redis的性能表現(xiàn),便可以大體了解代理造成的性能損耗。

我們選取B1、B2兩個(gè)Dynomite以及其代理的Redis來(lái)進(jìn)行壓測(cè)分析。由于實(shí)際使用時(shí)發(fā)現(xiàn)數(shù)據(jù)并不是隨機(jī)或者平均落到B1、B2對(duì)應(yīng)的Redis節(jié)點(diǎn),而是所有數(shù)據(jù)都落到了B1代理的Redis中,數(shù)據(jù)分片的規(guī)則需要再分析。所以對(duì)Dynomite壓測(cè)時(shí),數(shù)據(jù)在本身代理的Redis中比起不在的情況,可能性能有區(qū)別。

所以我們分別在本機(jī)對(duì)B1、B2以及B1代理的Redis進(jìn)行壓測(cè),之后再在服務(wù)器A對(duì)B1、B2進(jìn)行壓測(cè),將得到的五個(gè)壓測(cè)數(shù)據(jù)進(jìn)行對(duì)比。

壓測(cè)的指令參數(shù)如下

redis-benchmark -h ip -p 端口 -r 1000000 -t get,set,lpush,lpop -n 500000 -c 300 -d 1000 -q

壓測(cè)結(jié)果如下

壓測(cè)目標(biāo) 本機(jī)壓測(cè) 同區(qū)服務(wù)器壓測(cè)
B1代理的Redis SET 99265 GET 94607 SET 50080 GET 47943
B1 SET 69070 GET 82331 SET 48642 GET 47888
B2 SET 69851 GET 79833 SET 50241 GET 48971

可以看出本機(jī)訪問Dynomite比起直接訪問Reids有接近三成的性能損耗;不同Dynomite節(jié)點(diǎn)之間性能差別基本可以忽略;同區(qū)云服務(wù)訪問Dynomite代理的性能和直接訪問Redis相比幾乎沒差別,應(yīng)該是因?yàn)镈ynomite對(duì)Redis的連接使用了 pipelinie 功能。

由于實(shí)際使用時(shí),服務(wù)和Redis一般不在一個(gè)服務(wù)器上,所以Dynomite的性能表現(xiàn)比較理想。

5、對(duì)Redis指令支持度

支持度較高,除了以下情況外未發(fā)現(xiàn)其他不支持的指令

  • keys * 、flushall、del key1 key2 等批量執(zhí)行指令實(shí)際上只能處理到Dynomite直接連接的Redis節(jié)點(diǎn)的數(shù)據(jù)。這很好理解,因?yàn)榕恐噶钜蕉鄠€(gè)實(shí)例去執(zhí)行并合并結(jié)果,執(zhí)行時(shí)間會(huì)較長(zhǎng),而且如果執(zhí)行結(jié)果只有部分正常,合并后的執(zhí)行結(jié)果將會(huì)相當(dāng)復(fù)雜。其中keys * 指令會(huì)獲取到Dynomite鏈接的Redis實(shí)例的key列表
  • 訂閱發(fā)布指令不支持,估計(jì)也是因?yàn)榧合卤容^難處理
  • 不支持 rename 指令

6、優(yōu)缺點(diǎn)及其應(yīng)用于生產(chǎn)環(huán)境的風(fēng)險(xiǎn)評(píng)估

優(yōu)點(diǎn)

  • 支持多主集群
  • 配置使用相對(duì)較為簡(jiǎn)單直觀
  • 比起直連Redis性能折損相當(dāng)少,可以忽略
  • 對(duì)Redis的支持度相當(dāng)高,完全足夠平時(shí)開發(fā)使用

缺點(diǎn)

  • 集群功能的輔助功能不夠完整,缺少不停機(jī)動(dòng)態(tài)擴(kuò)容功能
  • 缺少內(nèi)置的數(shù)據(jù)同步功能,新增節(jié)點(diǎn)
  • 缺少內(nèi)置的數(shù)據(jù)同步功能,Dynomite或Redis節(jié)點(diǎn)故障停機(jī)重啟后不會(huì)自動(dòng)從其他節(jié)點(diǎn)同步數(shù)據(jù)
  • 高可用功能有一定缺陷,Dynomite節(jié)點(diǎn)對(duì)應(yīng)的Redis掛掉之后,訪問這個(gè)節(jié)點(diǎn)時(shí),如果key是屬于這個(gè)Redis的會(huì)直接報(bào)錯(cuò),不會(huì)到其他數(shù)據(jù)中心拿數(shù)據(jù)
  • 文檔比較少特別是中文文檔,不夠詳細(xì),比如各類配置的可選項(xiàng)、各配置的關(guān)聯(lián)互動(dòng)、異常處理說(shuō)明、第三方配合使用工具說(shuō)明很少,
  • 社區(qū)不活躍
  • 更新有點(diǎn)慢,4-6個(gè)月更新一次代碼

缺點(diǎn)1可以通過Dynomite節(jié)點(diǎn)代理Redis哨兵模式或者Redis-cluster集群解決,但會(huì)帶來(lái)一定性能折損;2可以通過第三方數(shù)據(jù)同步工具做處理如Redis-migrate-tool、Redis-shake;3無(wú)法解決;4可以引入進(jìn)程進(jìn)程存活監(jiān)控,出問題后立刻重啟Redis,但期間丟失的數(shù)據(jù)也即是缺點(diǎn)3無(wú)法解決;其他無(wú)法解決。

其他風(fēng)險(xiǎn),分別用了兩個(gè)分支的最新版本,rel_0.6_prod_safe(2019.9.25更新)和0.6(2019.11.21更新)

  • rel_0.6_prod_safe分支 快速壓測(cè)幾百萬(wàn)個(gè)1k大小的數(shù)據(jù)包后,Dynomite服務(wù)掛掉的情況。
  • rel_0.6_prod_safe以及0.6分支出現(xiàn)max_msgs超過上限的錯(cuò)誤日志,之后停止壓測(cè)很長(zhǎng)時(shí)間在壓測(cè)仍然會(huì)出現(xiàn),出現(xiàn)這種錯(cuò)誤是會(huì)出現(xiàn)非常高的內(nèi)存占用,在redis只占用了不到3-5g內(nèi)存情況下,Dynomite占用了8-12G內(nèi)存。并且這個(gè)內(nèi)存不會(huì)下降,推測(cè)是未處理的消息堆積導(dǎo)致。
  • 0.6分支配置打開enable_gossip時(shí)啟動(dòng)服務(wù)后出現(xiàn)了使用redis-cli連接長(zhǎng)時(shí)間無(wú)響應(yīng)卡住的情況

對(duì)于數(shù)據(jù)庫(kù)集群方案,以下幾點(diǎn)非常重要

  • 1、零侵入:業(yè)務(wù)系統(tǒng)不需要做任何改造就能接入
  • 2、高吞吐量:基于現(xiàn)有業(yè)務(wù)峰值TPS乘以10,得出TPS要達(dá)到1萬(wàn)
  • 3、低延時(shí):我司的多活業(yè)務(wù)不會(huì)出現(xiàn)跨機(jī)房讀取數(shù)據(jù)的情況,所以定的目標(biāo)延時(shí)低于1s。實(shí)際情況延時(shí)在50ms左右
  • 4、高堆積能力:基于跨機(jī)房網(wǎng)絡(luò)的不確定性,當(dāng)網(wǎng)絡(luò)閃斷時(shí)能夠保證指令不丟失
  • 5、高可用性:當(dāng)網(wǎng)絡(luò)故障或者Redis宕機(jī)恢復(fù)時(shí),同步任務(wù)能自動(dòng)恢復(fù)
  • 6、可配置性:業(yè)務(wù)系統(tǒng)可以自由定制需要同步哪些Key

Dynomite在第1、2、3 方面做得比較好,第4支持但是有一定缺陷,第5不夠完善,6不支持。

總的來(lái)說(shuō)Dynomite作為集群方案是功能不夠完善,和Redis Cluster相比多了多主功能,但是缺失動(dòng)態(tài)擴(kuò)容、自動(dòng)同步數(shù)據(jù)等功能;高可用方面也有一定缺陷。社區(qū)活躍度和文檔都比較欠缺,更新較慢。生產(chǎn)環(huán)境使用風(fēng)險(xiǎn)較大。如果實(shí)在要用建議搭配Redis Cluster使用以解決動(dòng)態(tài)擴(kuò)容、新增節(jié)點(diǎn)和故障節(jié)點(diǎn)自動(dòng)同步數(shù)據(jù)等問題,并且應(yīng)該將其當(dāng)做緩存集群,避免當(dāng)做持久化數(shù)據(jù)庫(kù),特別是用戶數(shù)據(jù)等核心數(shù)據(jù)。

參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • NOSQL類型簡(jiǎn)介鍵值對(duì):會(huì)使用到一個(gè)哈希表,表中有一個(gè)特定的鍵和一個(gè)指針指向特定的數(shù)據(jù),如redis,volde...
    MicoCube閱讀 4,168評(píng)論 2 27
  • redis集群分為服務(wù)端集群和客戶端分片,redis3.0以上版本實(shí)現(xiàn)了集群機(jī)制,即服務(wù)端集群,3.0以下使用客戶...
    hadoop_null閱讀 1,687評(píng)論 0 6
  • feisky云計(jì)算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 4,383評(píng)論 0 5
  • 前言 Redis 是我們目前大規(guī)模使用的緩存中間件,由于它強(qiáng)大高效而又便捷的功能,得到了廣泛的使用。單節(jié)點(diǎn)的Red...
    Kevin_ZGJ閱讀 11,866評(píng)論 19 133
  • Zookeeper用于集群主備切換。 YARN讓集群具備更好的擴(kuò)展性。 Spark沒有存儲(chǔ)能力。 Spark的Ma...
    Yobhel閱讀 7,613評(píng)論 0 34

友情鏈接更多精彩內(nèi)容