十一、codis


一、紹介
Codisは分散Redisソリューションであり,上位層の応用にとってCodis Proxyに接続し,元の接続を行う. Redis Server 明らかな違いはなく、上層アプリケーションは単機を使用するようにすることができます. Redis 同様に使用すると、Codisの下位層はリクエストの転送、ダウンタイムのないデータ移行などの作業を処理し、すべての後のすべてのことは、前のクライアントにとって透明であり、後に接続されているのはメモリが無限大であると簡単に考えることができる. Redis サービス
コンポーネント
編集
  Codis Proxy (codis-proxy)
  Codis Manager (codis-config)
  Codis Redis (codis-server)
  ZooKeeper
codis-proxyはクライアント接続のRedisエージェントサービスであり,codis-proxy自体が実現している. Redis プロトコルは、1つのオリジナルのRedisと変わらず(Twemproxyのように)、1つのビジネスにとって、複数のcodis-proxyを配置することができ、codis-proxy自体は無状態である.
codis-configはCodisの管理ツールで、Redisノードの追加/削除、Proxyノードの追加/削除、データ移行の開始などの操作をサポートしています.codis-config自体にhttp serverが付いていて、1つの dashboard、ユーザーは直接ブラウザでCodisを観察することができます クラスタの動作状態
codis-serverはCodisプロジェクトのメンテナンスのRedis分岐であり、2.8.13の開発に基づいて、slotのサポートと原子のデータ移行命令を加えた.Codis上層のcodis-proxyとcodis-configはこのバージョンのRedisと対話してこそ正常に動作することができる.
CodisはZooKeeperに依存するデータルーティングテーブルとcodis-proxyノードのメタ情報を格納し、codis-configが発起するコマンドはZooKeeperによって各生存するcodis-proxyに同期する.
CodisはNamespaceによって異なる製品を区別することをサポートし、異なるproduct nameを持つ製品は、各構成が衝突しない
とくせい
編集
  じどうへいこう
  非常に簡単に使用できます  
  グラフィックパネルと管理ツール
  圧倒的多数を支持する Redis コマンド、完全互換twemproxy
  サポート Redis オリジナルクライアント
  安全で透明なデータマイグレーションにより、必要に応じてノードを簡単に追加および削除できます.
  コマンドラインインタフェースの提供
  RESTful APIs
利点:高い同時読み書きを実現し、データの一致性が高い.
欠点:性能に大きな損失があり、故障切替はkeyを失わないことを保証できず、読み書き分離ができない.
論理アーキテクチャは次のとおりです.
アクセス層:アクセス方式はvipまたはjavaコードでjodisを呼び出し、その後、異なるcodis-proxyアドレスを接続して呼び出すことで高利用可能なLVSとHA機能を実現することができる.
エージェント層:その後、中間層はcodis-proxyとzookeeperによってデータの進行と分配を処理し、crc 32アルゴリズムによってkeyを異なるredisのあるslotに平均的に分配する.raid 0のようなストライプ化を実現し、古いバージョンのcodisではslotは手作業で分配する必要があり、codis 3.2以降、slotは自動的に分配され、かなり便利である.
データ層:最後にcodis-proxyはデータを真実のredis-serverメインサーバに格納し、codisの著者である黄東旭はデータ整合性をかなり重視しているため、データ遅延によるデータ不一致は許されないため、アーキテクチャは最初から読み書きから分離することを考慮していない.サービスからはフェイルオーバーの冗長アーキテクチャとしてのみ、zookeeperがredis-sentinelを呼び出してフェイルオーバー機能を実現する.
マシンが限られているため、導入されたアーキテクチャは次のとおりです.
シーケンス番号
IP
ホスト名
デプロイメントプログラム
01
172.16.1.150
codis-porxy
codis-proxy:19000 codis-dashborad:18080、codis-fe:18090
02
172.16.1.151
codis-redis1
codis-server:(6379&6380) redis-sentinel:26379
03
172.16.1.152
codis-redis2
codis-server:(6379&6380) redis-sentinel:26379
04
172.16.1.153
codis-redis3
codis-server:(6379&6380) redis-sentinel:26379
1.goのインストール
cd /application/tools/
wget https://dl.google.com/go/go1.10.2.linux-amd64.tar.gz
tar -zxf go1.10.2.linux-amd64.tar.gz -C /usr/local/
cat <>/etc/profile
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=/usr/local/go/work
path=$PATH:$HOME/bin:$GOROOT/bin:$GOPATH/bin
EOF
source /etc/profile

2.codisの取得
wget https://github.com/CodisLabs/codis/archive/release3.2.zip
mkdir -p $GOPATH/src/github.com/CodisLabs
cd /usr/local/go/work/src/github.com/CodisLabs
unzip /application/tools/release3.2
mv codis-release3.2/ codis
cd codis/
make
#       ,   bin        codis-proxy、codis-server       。  , bin/assets      dashboard http          )
[root@codis-redis1 application]# ll /usr/local/go/work/src/github.com/CodisLabs/codis/bin
total 107560
drwxr-xr-x 4 root root     4096 Jun  2 03:57 assets
-rwxr-xr-x 1 root root 16237048 Jun  2 03:57 codis-admin
-rwxr-xr-x 1 root root 17222240 Jun  2 03:56 codis-dashboard
-rwxr-xr-x 1 root root 15512405 Jun  2 03:57 codis-fe
-rwxr-xr-x 1 root root 14457471 Jun  2 03:57 codis-ha
-rwxr-xr-x 1 root root 19425814 Jun  2 03:57 codis-proxy
-rwxr-xr-x 1 root root  7983449 Jun  2 03:56 codis-server
-rwxr-xr-x 1 root root  5578703 Jun  2 03:56 redis-benchmark
-rwxr-xr-x 1 root root  5710507 Jun  2 03:56 redis-cli
-rwxr-xr-x 1 root root  7983449 Jun  2 03:56 redis-sentinel
-rw-r--r-- 1 root root       97 Jun  2 03:59 version
[root@codis-porxy application]#

3.codis-server構成
  :   redis-3.2.8     。          ,    slot              。            redis    。
#  codis  
mkdir -p /application/codis/bin
mkdir /application/codis/conf
mkdir /application/codis/log
mkdir /application/codis/proc
mkdir /application/codis/data/redis_data_6380 -p
mkdir /application/codis/data/redis_data_6379 -p
cp -fr /usr/local/go/work/src/github.com/CodisLabs/codis/bin/* /application/codis/bin/
cp -fr /usr/local/go/work/src/github.com/CodisLabs/codis/config/* /application/codis/conf/
#     
cd /application/codis/conf/
#   
cp redis.conf redis-6379.conf
vim redis-6379.conf
bind 172.16.1.150
daemonize yes 
#  ID     
pidfile /application/codis/proc/redis-6379.pid 
#     
port 6379
timeout 86400 
tcp-keepalive 60 
loglevel notice 
#      
logfile "/application/codis/log/redis-6379.log"
databases 16 
save “” 
save 900 1 
save 300 10 
save 60 10000 
stop-writes-on-bgsave-error no 
rdbcompression yes 
#dump   
dbfilename dump-6379.rdb 
#dump   
dir /application/codis/data/redis_data_6379
#Master  (      )
masterauth "123456"  
slave-serve-stale-data yes 
repl-disable-tcp-nodelay no 
slave-priority 100 
#    (       )
requirepass "123456" 
maxmemory 10gb 
maxmemory-policy allkeys-lru 
appendonly no 
appendfsync everysec 
no-appendfsync-on-rewrite yes 
auto-aof-rewrite-percentage 100 
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000 
slowlog-log-slower-than 10000 
slowlog-max-len 128 
hash-max-ziplist-entries 512 
hash-max-ziplist-value 64 
list-max-ziplist-entries 512 
list-max-ziplist-value 64 
set-max-intset-entries 512 
zset-max-ziplist-entries 128 
zset-max-ziplist-value 64 
client-output-buffer-limit normal 0 0 0 
client-output-buffer-limit slave 0 0 0 
client-output-buffer-limit pubsub 0 0 0 
hz 10 
aof-rewrite-incremental-fsync yes 
repl-backlog-size 33554432

#     
cp redis-6379.conf redis-example.conf 
egrep -v "#|^$" redis-example.conf > redis-6380.conf
sed -i "s@6379@6380@g" redis-6380.conf
vim redis-6380.conf
bind 172.16.1.150
protected-mode yes
port 6380
tcp-backlog 511
timeout 86400
tcp-keepalive 60
daemonize yes
supervised no
pidfile /application/codis/proc/redis-6380.pid
loglevel notice
logfile "/application/codis/log/redis-6380.log"
databases 16
#save ""
#save 900 1
#save 300 10
#save 60 10000
stop-writes-on-bgsave-error no
rdbcompression yes
rdbchecksum yes
dbfilename dump-6380.rdb
dir /application/codis/data/redis_data_6380
masterauth 123456
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
repl-backlog-size 33554432
slave-priority 100
requirepass 123456
maxmemory 10gb
maxmemory-policy allkeys-lru
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 0 0 0
client-output-buffer-limit pubsub 0 0 0
hz 10
aof-rewrite-incremental-fsync yes

#  codis-server       
scp -r codis [email protected]:/application/
scp -r codis [email protected]:/application/

#    
vim /server/scripts/codis-server.sh
if [ $# -eq 0 ]
then
echo "useage:sh $0 {start|stop}"
exit 0
fi
case $1 in
start)
/application/codis/bin/codis-server /application/codis/conf/redis-6379.conf
/application/codis/bin/codis-server /application/codis/conf/redis-6380.conf
;;
stop) 
ps -ef|grep codis-server|grep -v grep|awk '{print $2}'|xargs kill
;;
esac

#         
scp /server/scripts/codis-server.sh [email protected]:/server/scripts/
scp /server/scripts/codis-server.sh [email protected]:/server/scripts/

#      
sh /server/scripts/codis-server.sh start

4.Codis-dashboard
  :      ,   codis-proxy、codis-server    、  ,        。          ,codis-dashboard         codis-proxy        。
1)           ,      codis-dashboard     0   1 ; 
2)              codis-dashboard   。

cd /application/codis/bin/
#    
./codis-dashboard --default-config | tee ../conf/dashboard.conf
vim ../conf/dashboard.conf
#       
coordinator_name = "zookeeper" 
#    IP  
coordinator_addr = "172.16.1.111:2181" 
#     
product_name = "my-codis" 
#    (  :   redis    requirepass    )
product_auth = "123456"
#RESTful API   
admin_addr = "0.0.0.0:18080" 
#      dashboard     OPS   0   ,   proxy IP      hosts   .
172.16.1.150    codis-porxy

#    
nohup ./codis-dashboard --ncpu=24 --config=/application/codis/conf/dashboard.conf --log=/application/codis/log/dashboard.log --log-level=WARN &

#  
./codis-admin --dashboard=172.16.1.150:18080 –auth=123456 --shutdown

5.Codis-proxy
  :       Redis     ,     Redis   。           (        ),        Redis     (   Twemproxy)。
1)           ,         codis-proxy   ; 
2)   codis-proxy     codis-dashboard       

#    
cd /application/codis/bin/
#    
./codis-proxy --default-config | tee ../conf/proxy.conf 
#    
vim ../conf/proxy.conf 
#      
product_name = "my-codis" 
#    dashboard   (  : redis requirepass  )
product_auth = "123456" 
#Redis        (  : redis requirepass   )
session_auth = "56789" 
# Set bind address for admin(rpc), tcp only. 
admin_addr = "0.0.0.0:11080" 
proto_type = "tcp4"
#    (Redis        )
proxy_addr = "0.0.0.0:19000" 
#       
jodis_name = "zookeeper"
#       
jodis_addr = "172.16.1.111:2181" 
jodis_timeout = "20s"
#         0          ”write: broken pipe”   
session_recv_timeout = "0s" 

#    
nohup ./codis-proxy --ncpu=24 --config=/application/codis/conf/proxy.conf --log=/application/codis/log/proxy.log  &

6.Redis-sentinel
  :Redis         (HA)    。      Redis   、  、      。  Master    ,            ,      Slave   Master,   Slave      Master  
#             
vim /application/codis/conf/sentinel.conf
bind 0.0.0.0 
protected-mode no 
port 26379 
dir /application/codis/data/
scp /application/codis/conf/sentinel.conf [email protected]:/application/codis/conf/
scp /application/codis/conf/sentinel.conf [email protected]:/application/codis/conf/

#    
nohup /application/codis/bin/redis-sentinel /application/codis/conf/sentinel.conf &

7.Codis-fe
  :      。
1)                     ; 
2)          codis-dashboard  ,         

#    
cd /application/codis/bin/
./codis-admin --dashboard-list --zookeeper=172.16.1.111:2181 | tee ../conf/codis.json
[
    {
        "name": "my-codis",
        "dashboard": "codis-porxy:18080"
    },
    {
        "name": "codis-chinasoft",
        "dashboard": "172.16.1.150:18080"
    }
]

#    
nohup ./codis-fe --ncpu=1 --log=/application/codis/log/fe.log --log-level=WARN --zookeeper=172.16.1.111:2181 --listen=172.16.1.150:8090 &

#アクセス172.16.1.150:8090設定
proxyの追加
codis-serverの追加
redis-sentinelsの追加
構成slots
8.POST関連設定
#codis-server+Redis-sentinel
vim /server/scripts/sentinel.sh
if [ $# -eq 0 ]
then
echo "useage:sh $0 {start|stop}"
exit 0
fi
case $1 in
start)
nohup /application/codis/bin/redis-sentinel /application/codis/conf/sentinel.conf &
;;
stop) 
ps -ef|grep redis-sentinel|grep -v grep|awk '{print $2}'|xargs kill
;;
esac
vim /server/scripts/auto_start_codis.sh
 sh /server/scripts/codis-server.sh start
 sh /server/scripts/sentinel.sh start
chmod +x /server/scripts/auto_start_codis.sh
vim /etc/rc.local
 /server/scripts/auto_start_codis.sh
 
#Codis-fe + Codis-proxy + Codis-dashboard
vim /server/scripts/codis.sh
export GO_HOME=/usr/local/go/bin/
if [ $# -eq 0 ]
then
echo "useage:sh $0 {start|stop}"
exit 0
fi
case $1 in
start)
nohup /application/codis/bin/codis-dashboard --ncpu=24 --config=/application/codis/conf/dashboard.conf --log=/application/codis/log/dashboard.log --log-level=WARN &
nohup /application/codis/bin/codis-proxy --ncpu=24 --config=/application/codis/conf/proxy.conf --log=/application/codis/log/proxy.log &
nohup /application/codis/bin/codis-fe --ncpu=1 --log=/application/codis/log/fe.log --log-level=WARN --zookeeper=172.16.1.111:2181 --listen=172.16.1.150:8090 &
;;
stop)
ps -ef|grep codis-proxy|grep -v grep|awk '{print $2}'|xargs kill
ps -ef|grep codis-fe|grep -v grep|awk '{print $2}'|xargs kill
ps -ef|grep codis-dashboar|grep -v grep|awk '{print $2}'|xargs kill
chmod +x /server/scripts/codis.sh
vim /etc/rc.local
 /server/scripts/codis.sh start
 
#       ,       ,  codis-dashboard      .    zookeeper         ,      codis-dashboard     zookeeper,             .          product
/application/codis/bin/codis-admin --remove-lock --product=my-codis --zookeeper=172.16.1.111:2181
#    
nohup /application/codis/bin/codis-dashboard --ncpu=24 --config=/application/codis/conf/dashboard.conf --log=/application/codis/log/dashboard.log --log-level=WARN &

9.性能テスト
redis-benchmarkパラメータ解析:
-h    ipアドレス
-p    redisポート
-a    認証パスワード
-c    複数の同時接続を設定
-n    全部で何個お願いしますか
-q    表示モードひょうじもーど:簡易モードたんじゅんもーど
#    
/application/codis/bin/redis-benchmark -h 172.16.1.150 -p 19000 -a 56789 -c 500 -n 1000000 -q

#     
/application/codis/bin/redis-benchmark -h 172.16.1.151 -p 6739 -a 56789 -c 500 -n 1000000 -q

10.読み書き分布テスト
vim /server/scripts/test_codis.sh
#!/bin/bash
hos="172.16.1.150"
pot="19000"
pawd="56789"
cli="/application/codis/bin/redis-cli"
keyset="keytest2"
valueset="jlasdnfnsdfsdf;sdfhlkjahsdjlkfadfjkasdbbcjhdgasfyuefkbadjkhflk"
dbname=2
a=0
for i in `seq 1 5000`
do
        $cli -h $hos -p $pot -a $pawd -n $dbname 'set' ${keyset}${a} "${valueset}${a}" >/dev/null
        #echo $a
        let a++
done

sh /server/scripts/test_codis.sh

keyの基本平均分布は3つのグループにある
11.フェイルオーバーテスト
#      
vim 
#!/bin/bash
hos="172.16.1.150"
pot="19000"
pawd="56789"
cli="/application/codis/bin/redis-cli"
keyset="test2"
valueset="asdklalksjdklajsdlkajs"
dbname=2
a=0
for i in `seq 1 6000`
do
        $cli -h $hos -p $pot -a $pawd -n $dbname 'set' ${keyset}${a} "${valueset}${a}" >/dev/null
        #echo $a
        let a++
done

sh /server/scripts/test_codis.sh
#      ss -ntplu | grep codis-server(172.16.1.152)
tcp    LISTEN     0      128         172.16.1.152:6379         *:*      users:(("codis-server",1068,4))
tcp    LISTEN     0      128         172.16.1.152:6380         *:*      users:(("codis-server",1073,4))
#      
kill -9 1068

合計5100個KEY 
KEYを失う問題は、redis-sentinelフェイルオーバーの間、codisクラスタ全体がこのフェイルオーバredis-serverの接続を閉じることがないため、codis-proxyは依然として現在のフェイルオーバredis-serverにデータを送信するが、この場合のredis-serverはデータを格納できないことが明らかになり、これはkeyを失う現象をもたらした.障害ノードを手動で除去しない限り、このredis-serverに送信されたkeyはすべて失われます.
codisにはフェイルオーバープログラムcodis-haも付属していますが、彼はデーモンプロセスに属し、codis-dashboardに接続して各ノードの状態を表示します.
1
2
#コマンドを実行してcodis-haを起動します.ポートはcodis-dashboardのポートです.
/usr/local/codis/codis-ha 
--dashboard=172.16.1.150:18080 --log=
/application/codis/log/ha
.log --log-level=WARN &
--dashboard    dashboardのアドレスとポートの指定
--log         ログファイルの指定
--log-level    指定ログレベル、INFO,WARN,DEBUG,ERROR
しかし、このソフトにも欠陥があり、dashboardに自動的に接続する各主従構造の健康情報を検出し、検出間隔が速く(デフォルト3秒、パラメータ--intervalを変更可能)、障害を検出すると、障害マスターライブラリまたはライブラリから強制的にオフラインになり、dashboardに登録する情報を削除する.
切替速度は非常に速く、キーを失う現象は少ない(3秒でなくす)が、後で故障した古いメインライブラリを強制的にオフラインにし、手動で構成を修正してredis-server(codis-server)を再起動し、codis-feインタフェースに構成を追加する必要がある.
全自動管理ができないのは明らかで、少し面倒で、redis-sentinelも意味がないので、2つの方法で1つを選ぶしかありません.
キーを失う現象は少なく見えるが、キーを失う場合もあり、50ステップ100ステップとしか言いようがなく、このグループ内の他のslaveインスタンスは自動的に状態を変えることはなく、これらのslaveは古いmasterからデータを同期しようとするため、グループ内の新しいmasterと他のslaveの間のデータが一致しない.従って、主従切替が発生すると、管理者が手動で新しいsync actionを作成して新しいmasterとslave間のデータ同期を完了する必要があり、逆に手動操作の作業量が増加し、codis-haとredis-sentinelのクラスタの選択について実際の状況を考慮する必要がある.
したがって、あくまでcodisのフェイルオーバーがうまくいっていないので、keyを失うことを許容できればredis-sentinelを開くだけで十分であり、データ整合性の要求が高い場合は、codis-haを開いて足を踏み入れたほうが本来実現するほうがよく、それぞれ必要とする.