Redisクラスタコンテナ化インストール
1.Redisクラスタの概要
Redisは、現在非常に人気のあるメモリ型データ構造ストレージとして、データストレージ、キャッシュ、Message Agentなどに使用できます.この文書では、dockerに基づいてRedisクラスタを構築する方法について説明します.Redisのクラスタ設計には、プライマリスレーブレプリケーションとハッシュSlotの2つの部分が含まれています.
1.1. マスターコピー
プライマリ・スレーブ・レプリケーションはデータベースでよく見られ、一般的には読み書き分離に使用されます.Redisでもそうです.要求は1つのMaster(メインノード)のみで、N個のslaver(スレーブノード)を持つことができ、Slaverも自分のSlaverを持つことができ、このような主従の関係は彼らが配置段階で彼らの上下関係を指定することを決定し、Zookeeperのような平行関係は自主的に最適化されたものではない.
読み書きが分離され、MasterはSlaverにデータの書き込みと同期しか担当していないため、Slaverは読み出されるタスクを担当しているため、Slaverの拡張は読み書き効率を高めるだけで、書き込み効率を高めることはできない.
SlaverはまずMaster側で取得した情報をディスクに押し込み、メモリにロードし、client側はメモリから情報を読み出します.新しいSlaverがこのクラスタに加わると、自発的にMasterを探して埠頭を拝みに来ます.Masterは新しい弟を発見した後、全量のデータを新しいSlaverに送信します.データ量が大きいほど性能消費も大きくなりますので、実行時にSlaverの拡張を避けるようにします.
1.2. ハッシュSlot
ハッシュSlotの名前はわかりにくいかもしれませんが、実はデータベースの「水平分割」です.データベースのテーブルパーティションを知っていれば、ハッシュSlotの説明は、データベースのテーブルパーティションの「HASHパーティション」と原理的にほぼ同じであることがわかります.
オブジェクトがRedisに保存される前に、CRC 16を介して指定されたノードにハッシュされ、例えば図中のObject 4が最終的にノード1にハッシュされる.
各ノードは1つのSlotセグメントを平均的に割り当てられ、0-16384に対応し、Slotは繰り返したり欠落したりすることはできません.そうしないと、オブジェクトが繰り返し保存されるか、保存されないことになります.
ノード間も互いに傍受し合い,ノードが脱退したり加入したりするとSlot単位でデータの移行を行う.例えば、Node 1がオフラインになった場合、0-5640のこれらのSlotは平均的にNode 2とNode 3に割り当てられます.Node 2とNode 3自体がメンテナンスしているSlotは、自身に再割り当てされないため、移行中に5641-16384 Slotセグメントの使用には影響しません.
1.3. 二つを一つにする
ここを見ると、主従とハッシュの設計の長所と短所はちょうど互いに補完されており、両者を結合することはRedisクラスタの究極の形態であり、まずHashが論理ノードを分割し、その後、各論理ノードの内部が主従であることがわかります.
2.クラスタインストール
デフォルトではdocker環境がありますが、dockerベースのRedisクラスタのインストールを開始します.redis 5.0バージョンの前に、ネット上ではredis-tribを通じて多くのチュートリアルが行われていました.rbはクラスタを作成しますが、redis 5.0以降はredis-cliでしか実現できません.本稿では,redis−cliによりクラスタを作成するが,redisクラスタのノード選択方式は半数以上のmasterが通過する必要があるため,奇数個のノードを作成することを提案する.この例では3つのMasterノードを作成し、Masterノードごとに1つのSlaveノードを割り当てます.
2.1. ホスト環境
まず元のredisを探す必要があります.confファイル、名前をredis-clusterと変更します.tmplは、各redisインスタンスのredisを生成するためのいくつかのパラメータを構成する.conf:
[root@kerry2 redis]# wget https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf
[root@kerry2 redis]# mv redis.conf redis-cluster.tmpl
vi redis-cluster.tmpl
# bind 127.0.0.1
protected-mode no
port ${PORT}
daemonize no
dir /data/redis
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
次に、次のスクリプトを実行して、3つのMasterと3つのSlaveにそれぞれのマウントボリュームディレクトリを作成します.
# master slave
for port in `seq 7700 7705`; do
ms="master"
if [ $port -ge 7703 ]; then
ms="slave"
fi
mkdir -p ./$ms/$port/ && mkdir -p ./$ms/$port/data \
&& PORT=$port envsubst < ./redis-cluster.tmpl > ./$ms/$port/redis.conf;
done
現在のディレクトリ構造は
[root@kerry2 redis]# tree
.
├── master
│ ├── 7700
│ │ ├── data
│ │ └── redis.conf
│ ├── 7701
│ │ ├── data
│ │ └── redis.conf
│ └── 7702
│ ├── data
│ └── redis.conf
├── redis-cluster.tmpl
├── slave
├── 7703
│ ├── data
│ └── redis.conf
├── 7704
│ ├── data
│ └── redis.conf
└── 7705
├── data
└── redis.conf
2.2. Redisノードの作成
単純なdocker環境のみを考慮し,docker-composeやk 8 sのようなサービス編成はなく,各redisコンテナ間で通信を保証しなければならず,docker networkを作成することができると仮定する.(マイクロサービスを利用して編成する場合は、後で検討する)
[root@kerry2 redis]# docker network create redis-cluster-net
docker redisのmasterインスタンスとslaveインスタンスを実行できます
# docker redis master slave
for port in `seq 7700 7705`; do
ms="master"
if [ $port -ge 7703 ]; then
ms="slave"
fi
docker run -d -p $port:$port -p 1$port:1$port \
-v $PWD/$ms/$port/redis.conf:/data/redis.conf \
-v $PWD/$ms/$port/data:/data/redis \
--restart always --name redis-$ms-$port --net redis-cluster-net \
redis redis-server /data/redis.conf;
done
作成したredisコンテナの表示
[root@kerry2 redis]# docker ps |grep redis
010f295922e3 redis "docker-entrypoint..." 41 seconds ago Up 36 seconds 0.0.0.0:7705->7705/tcp, 6379/tcp, 0.0.0.0:17705->17705/tcp redis-slave-7705
b5d89f0469ee redis "docker-entrypoint..." 45 seconds ago Up 40 seconds 0.0.0.0:7704->7704/tcp, 6379/tcp, 0.0.0.0:17704->17704/tcp redis-slave-7704
f710e805fe96 redis "docker-entrypoint..." 50 seconds ago Up 45 seconds 0.0.0.0:7703->7703/tcp, 6379/tcp, 0.0.0.0:17703->17703/tcp redis-slave-7703
b187603aec65 redis "docker-entrypoint..." 55 seconds ago Up 50 seconds 0.0.0.0:7702->7702/tcp, 6379/tcp, 0.0.0.0:17702->17702/tcp redis-master-7702
ea635bd8b3dc redis "docker-entrypoint..." About a minute ago Up 55 seconds 0.0.0.0:7701->7701/tcp, 6379/tcp, 0.0.0.0:17701->17701/tcp redis-master-7701
f02a468572ca redis "docker-entrypoint..." About a minute ago Up About a minute 0.0.0.0:7700->7700/tcp, 6379/tcp, 0.0.0.0:17700->17700/tcp redis-master-7700
2.3. クラスタの構築
redis-cliコマンドでクラスタを構築し、redisコンテナを任意に探し、redis-cli--cluster create--cluster-replicas 1 ip:portコマンドを実行すればよい
[root@kerry2 redis]# docker exec -it redis-master-7700 redis-cli --cluster create ip:7700 ip:7701 ip:7702 ip:7703 ip:7704 ip:7705 --cluster-replicas 1
# yes ,
クラスタの構築時に、ノードredisデータが空であることを保証します.そうしないと、次のエラーが発生します.
[ERR] Node 172.18.0.2:7700 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
2.4. クラスタ検証
クラスタ構築が完了したら、redis-cliコマンドでクラスタノードに接続して検証します.redisクラスタノードの接続コマンドはredis-cli-c-h${ip}-p${port}
[root@kerry2 ~]# docker exec -it redis-master-7700 redis-cli -c -h ip -p 7700
ip :7700> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:23838
cluster_stats_messages_pong_sent:24283
cluster_stats_messages_sent:48121
cluster_stats_messages_ping_received:24278
cluster_stats_messages_pong_received:23838
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:48121
ip :7700> cluster nodes
056b99fe5993510c264e3e9a1fd1a04144da6a7b 172.18.0.2:7700@17700 myself,master - 0 1558578383000 1 connected 0-5460
73376f00b2837309d77b82d98984715f44eb2dcf ip:7704@17704 slave 056b99fe5993510c264e3e9a1fd1a04144da6a7b 0 1558578388562 5 connected
20e4b509a54fb17ed8d0f6c21bbc8693ab715ee7 ip:7705@17705 slave 1bcb0a6ac770e261c5b0de21cfe26b0bd614590e 0 1558578386658 6 connected
1bcb0a6ac770e261c5b0de21cfe26b0bd614590e ip:7701@17701 master - 0 1558578386579 2 connected 5461-10922
07a4c19848d578ac339bfaf741e1edfd0b010b08 ip:7702@17702 master - 0 1558578388661 3 connected 10923-16383
506271ed3f0657f05f439108d9372b638d2c4571 ip:7703@17703 slave 07a4c19848d578ac339bfaf741e1edfd0b010b08 0 1558578386000 4 connected
「cluster info」コマンドでクラスタの基本情報が表示され、すべてのslot(16384)が割り当てられていることがわかります.次に、「cluster nodes」コマンドを使用して、各masterノードのslot割り当ての領域を表示します.これでredisクラスタの基本的なインストールに成功しました.
3.後期運転次元
3.1. 基本コマンド
クラスタ
cluster info :
cluster nodes : ( node), 。
ノード
cluster meet : ip port , 。
cluster forget : node_id 。
cluster replicate : node_id 。
cluster saveconfig : 。
スロット
cluster addslots [slot ...] : ( slot) ( assign) 。
cluster delslots [slot ...] : 。
cluster flushslots : , 。
cluster setslot node : slot node_id ,
, >, 。
cluster setslot migrating : slot node_id 。
cluster setslot importing : node_id slot 。
cluster setslot stable : slot ( import) ( migrate)。
cluster keyslot : key 。
cluster countkeysinslot : slot 。
cluster getkeysinslot : count slot
3.2. よくある質問
(1)redis−clusterはすべての物理ノードを[0~16383]個のslot(ハッシュスロット)にマッピングし,clusterはnodeslotvalueのメンテナンスを担当する.
(2)クラスタのいずれかのノードで、masterがオフになっているが、slaverがある場合、slaveは自動的にmasterに上昇し、システムは正常である.
(3)クラスタのいずれかのノードでmasterが停止しslaverがない場合,クラスタはfail状態に入る.
(4)クラスタが半数以上のノードのmasterを切ると,slaverがあるかどうかにかかわらずクラスタはfail状態に入る.
(5)ノードが失効したか否かを判断する選挙は,クラスタ内のすべてのmasterが関与しており,半数以上のmasterノードが現在検出されているmasterノードと通信検出タイムアウト(cluster-node-timerout)すると,現在のmasterノードが停止していると考えられる.