Dockerを使用してRedisクラスターを構築する方法

Dockerを使用してRedisクラスターを構築する方法

概要: docker に触れて以来、あらゆるアプリケーション ソフトウェアを docker 方向にインストールする癖がついてしまったようです。今日は、docker を使用して redis クラスターを構築してみたいと思います。

まず、理論的な知識が必要です。Redis Cluster は Redis の分散ソリューションであり、Redis の単一マシン集中化の問題を解決します。分散データベース - まず、パーティション分割ルールに従ってデータセット全体を複数のノードにマッピングするという問題を解決します。

ここでは、パーティション分割ルール、つまりハッシュ パーティション分割ルールを知っておく必要があります。 Redis クラスターは、ハッシュ パーティション分割ルールで仮想スロット パーティション分割を使用します。すべてのキーはハッシュ関数に従って 0 ~ 16383 にマッピングされ、計算式は slot = CRC16(key)&16383 です。各ノードは、スロットの一部と、スロットによってマップされたキー値データを管理する責任があります。

1. Redis Dockerベースイメージを作成する

redisインストールパッケージをダウンロードし、バージョン4.0.1を使用します。

[root@etcd1 tmp]# mkdir docker_redis_cluster
[root@etcd1 tmp]# cd docker_redis_cluster/
[root@etcd2 docker_redis_cluster]# wget http://download.redis.io/releases/redis-4.0.1.tar.gz

redisを解凍してコンパイルする

[root@etcd1 docker_redis_cluster]# tar zxvf redis-4.0.1.tar.gz
[root@etcd1 docker_redis_cluster]# cd redis-4.0.1/
[root@etcd1 redis-4.0.1]# 作成

Redisの設定を変更する

[root@etcd3 redis-4.0.1]# vi /tmp/docker_redis_cluster/redis-4.0.1/redis.conf

バインドIPアドレスを変更する

# ~~~ 警告 ~~~ Redisを実行しているコンピュータが
# インターネットでは、すべてのインターフェースにバインドすることは危険であり、
# インスタンスをインターネット上の全員に公開します。デフォルトでは、
# 次のbindディレクティブにより、Redisは
# IPv4ルックバックインターフェースアドレス(これによりRedisは
# 同じコンピュータで実行されているクライアントからの接続のみを受け入れる
# は実行中です。
#
# インスタンスがすべてのインターフェースをリッスンするようにしたい場合は
# 次の行をコメントするだけです。
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#127.0.0.1 をバインドします
0.0.0.0 をバインド

デーモンプロセスを「はい」から「いいえ」に変更します

# デフォルトでは、Redis はデーモンとして実行されません。必要な場合は「yes」を使用してください。
# Redis はデーモン化されると /var/run/redis.pid に pid ファイルを書き込むことに注意してください。
悪魔化する

パスワード項目のコメントを解除し、新しいパスワードを追加します

# 警告: Redisは非常に高速なので、外部のユーザーは最大
# 良いマシンに対して1秒あたり15万のパスワード。つまり、
# 非常に強力なパスワードを使用してください。そうしないと、簡単に破られてしまいます。
#
# requirepass foobared

変更後

# 警告: Redisは非常に高速なので、外部のユーザーは最大
# 良いマシンに対して1秒あたり15万のパスワード。つまり、
# 非常に強力なパスワードを使用してください。そうしないと、簡単に破られてしまいます。
#
パスワード 123456

パスワードが設定されているため、設定内の別のマスタースレーブ接続にもパスワードを設定する必要があります。

# マスターがパスワード保護されている場合(「requirepass」設定を使用)
# 以下のディレクティブを使用すると、スレーブに認証する前に
# レプリケーション同期プロセスを開始します。そうでない場合は、マスターが
# スレーブ要求を拒否します。
#
# masterauth <マスターパスワード>

変更後

# マスターがパスワード保護されている場合(「requirepass」設定を使用)
# 以下のディレクティブを使用すると、スレーブに認証する前に
# レプリケーション同期プロセスを開始します。そうでない場合は、マスターが
# スレーブ要求を拒否します。
#
# masterauth <マスターパスワード>
マスター認証 123456

ログパスを設定する

# ログファイル名を指定します。また、空の文字列を使用して強制的に
# Redisは標準出力にログを記録します。標準出力を使用する場合は、
# ログ出力ですがデーモン化されており、ログは /dev/null に送信されます
ログファイル "/var/log/redis/redis-server.log"

クラスタ関連情報を設定し、設定項目の前のコメントを削除します。

# 通常のRedisインスタンスはRedis Clusterの一部にはなれません。
# クラスタノードとして起動できます。Redisインスタンスをクラスタノードとして起動するには、
# クラスター ノードでは、次のコメントを解除してクラスター サポートを有効にします。
#
クラスタ対応 はい
 
# 各クラスタノードにはクラスタ構成ファイルがあります。このファイルは
# 手動で編集することを目的としています。Redis ノードによって作成および更新されます。
# Redis Cluster ノードごとに異なるクラスター構成ファイルが必要です。
# 同じシステムで実行されているインスタンスに
# クラスター構成ファイル名が重複しています。
#
クラスター構成ファイル nodes-6379.conf
 
# クラスタノードタイムアウトは、ノードが到達不能になる必要があるミリ秒数です
# 失敗状態とみなされます。
# その他のほとんどの内部時間制限は、ノードのタイムアウトの倍数です。
#
クラスターノードタイムアウト 15000

ミラーイメージ制作

[root@etcd3 docker_redis_cluster]# cd /tmp/docker_redis_cluster
[root@etcd3 docker_redis_cluster]# vi Dockerファイル
# レディス
# バージョン 4.0.1
 
Centos:7 から<br>
ENV REDIS_HOME /usr/local<br>
ADD redis-4.0.1.tar.gz / # ローカルの redis ソース パッケージがイメージのルート パスにコピーされます。ADD コマンドは、コピー後に自動的に解凍します。コピーしたオブジェクトは Dockerfile と同じパスにある必要があり、ADD RUN mkdir -p $REDIS_HOME/redis # インストール ディレクトリを作成します。ADD redis-4.0.1/redis.conf $REDIS_HOME/redis/ # コンパイルの開始時に生成および変更された構成をインストール ディレクトリにコピーします。RUN yum -y update # yum ソースを更新します。RUN yum install -y gcc make # コンパイルに必要なツールをインストールします。WORKDIR /redis-4.0.1
実行して作る
RUN mv /redis-4.0.1/src/redis-server $REDIS_HOME/redis/ # コンパイル後、コンテナには実行ファイル redis-server のみが必要です
 
ワークディレクトリ /
RUN rm -rf /redis-4.0.1 # 解凍したファイルを削除します RUN yum remove -y gcc make # インストールとコンパイルが完了したら、不要なgccとmakeを削除します
 
VOLUME ["/var/log/redis"] # データボリュームを追加します。 EXPOSE 6379 # ポート 6379 を公開します。複数のポートを公開することもできますが、ここでは必要ありません。

PS. 現在のイメージは実行可能イメージではないため、ENTRYPOINTおよびCMD命令は含まれていません。

イメージを構築する

# 中国語ソースに切り替える [root@etcd3 docker_redis_cluster]# vi /etc/docker/daemon.json
{
  "レジストリミラー": ["https://registry.docker-cn.com"]
}
 
# [root@etcd3 docker_redis_cluster]# docker build -t hakimdstx/cluster-redis をコンパイルします。
...
 
完了!
 ---> 546cb1d34f35
中間コンテナ 6b6556c5f28d を削除しています
ステップ14/15: ボリューム/var/log/redis
 ---> 05a6642e4046 で実行中
 ---> e7e2fb8676b2
中間コンテナ 05a6642e4046 の削除
ステップ 15/15: EXPOSE 6379
 ---> 5d7abe1709e2 で実行中
 ---> 2d1322475f79
中間コンテナ 5d7abe1709e2 を削除
2d1322475f79 の構築に成功しました

イメージが作成されました。作成中に、次のエラーが表示される場合があります: glibc-headers-2.17-222.el7.x86_64.rpm の公開キーがインストールされていません。この場合、イメージ構成にコマンドを追加する必要があります:

...
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7を実行します。
RUN yum -y update # yumソースを更新 RUN yum install -y gcc make # コンパイルに必要なツールをインストール

画像を表示:

[root@etcd3 docker_redis_cluster]# docker イメージ
リポジトリ タグ イメージ ID 作成 サイズ
hakimdstx/cluster-redis 4.0.1 1fca5a08a4c7 14 秒前 435 MB
centos 7 49f7960eb7e4 2日前 200 MB

以上で、Redisの基本イメージは完成です

2. Redisノードイメージを作成する

以前に作成したRedisベースイメージに基づいてRedisノードイメージを作成します。

[root@etcd3 tmp]# mkdir docker_redis_nodes
[root@etcd3 tmp]# cd docker_redis_nodes
[root@etcd3 docker_redis_nodes]# vi Dockerファイル
# Redis ノード
# バージョン 4.0.1<br>
hakimdstx/cluster-redis:4.0.1 より
 
#メンテナー情報
メンテナー hakim [email protected]
 
エントリポイント ["/usr/local/redis/redis-server", "/usr/local/redis/redis.conf"]

Redisノードイメージを構築する

[root@etcd3 docker_redis_nodes]# docker build -t hakimdstx/nodes-redis:4.0.1 。      
ビルド コンテキストを Docker デーモンに送信しています 2.048 kB
ステップ 1/3: hakimdstx/cluster-redis:4.0.1 から
 ---> 1fca5a08a4c7
ステップ 2/3: MAINTAINER hakim [email protected]
 ---> cc6e07eb2c36 で実行中
 ---> 55769d3bfacb
中間コンテナ cc6e07eb2c36 を削除しています
ステップ 3/3: ENTRYPOINT /usr/local/redis/redis-server /usr/local/redis/redis.conf
 ---> f5dedf88f6f6 で実行中
 ---> da64da483559
中間コンテナ f5dedf88f6f6 を削除しています
da64da483559 の構築に成功しました

ミラーを見る

[root@etcd3 docker_redis_nodes]# docker イメージ
リポジトリ タグ イメージ ID 作成 サイズ
hakimdstx/nodes-redis 4.0.1 da64da483559 51 秒前 435 MB
hakimdstx/cluster-redis 4.0.1 1fca5a08a4c7 9 分前 435 MB
centos 7 49f7960eb7e4 2日前 200 MB

3. Redisクラスターを実行する

Redisコンテナを実行する

[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6379 -p 6379:6379 hakimdstx/nodes-redis:4.0.1  
1673a7d859ea83257d5bf14d82ebf717fb31405c185ce96a05f597d8f855aa7d
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6380 -p 6380:6379 hakimdstx/nodes-redis:4.0.1   
df6ebce6f12a6f3620d5a29adcfbfa7024e906c3af48f21fa7e1fa524a361362
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6381 -p 6381:6379 hakimdstx/nodes-redis:4.0.1  
396e174a1d9235228b3c5f0266785a12fb1ea49efc7ac755c9e7590e17aa1a79
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6382 -p 6382:6379 hakimdstx/nodes-redis:4.0.1
d9a71dd3f969094205ffa7596c4a04255575cdd3acca2d47fe8ef7171a3be528
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6383 -p 6383:6379 hakimdstx/nodes-redis:4.0.1
73e4f843d8cb28595456e21b04f97d18ce1cdf8dc56d1150844ba258a3781933
[root@etcd3 docker_redis_nodes]# docker run -d --name redis-6384 -p 6384:6379 hakimdstx/nodes-redis:4.0.1
10c62aafa4dac47220daf5bf3cec84406f086d5261599b54ec6c56bb7da97d6d

コンテナ情報の表示

[root@etcd3 redis]# docker ps
コンテナID イメージ コマンド 作成ステータス ポート名
10c62aafa4da hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 秒前 2 秒前にアップ 0.0.0.0:6384->6379/tcp redis-6384
73e4f843d8cb hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 12 秒前 10 秒前にアップ 0.0.0.0:6383->6379/tcp redis-6383
d9a71dd3f969 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 20 秒前 18 秒前に起動 0.0.0.0:6382->6379/tcp redis-6382
396e174a1d92 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6381->6379/tcp redis-6381
df6ebce6f12a hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6380->6379/tcp redis-6380
1673a7d859ea hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6379->6379/tcp redis-6379

Redisクラスタコンテナを実行する

リモート接続を介してRedis Infoレプリケーション情報を表示する

[root@etcd2 ~]# redis-cli -h 192.168.10.52 -p 6379
192.168.10.52:6379> 情報レプリケーション
NOAUTH 認証が必要です。
192.168.10.52:6379> 認証 123456
わかりました
192.168.10.52:6379> 情報レプリケーション
# レプリケーション
役割:マスター
接続されたスレーブ:0
マスター返信ID:2f0a7b50aed699fa50a79f3f7f9751a070c50ee9
マスター返信ID2:0000000000000000000000000000000000000000000
マスター_repl_オフセット:0
秒_repl_offset:-1
repl_backlog_active:0
レプリケーションバックログサイズ:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
192.168.10.52:6379>
# 残りの基本情報は上記と同じです

顧客が接続した後、パスワードが事前に設定されているため、最初に認証のためにパスワードを入力する必要があり、そうしないと通過できないことがわかります。上記の情報から、すべての Redis がマスター ロール role:master にあることがわかりますが、これは明らかに望ましいことではありません。

設定の前に、すべてのコンテナの現在のIPアドレスを確認する必要があります。

[root@etcd3 redis]# docker ps
コンテナID イメージ コマンド 作成ステータス ポート名
10c62aafa4da hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 秒前 2 秒前にアップ 0.0.0.0:6384->6379/tcp redis-6384
73e4f843d8cb hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 12 秒前 10 秒前にアップ 0.0.0.0:6383->6379/tcp redis-6383
d9a71dd3f969 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 20 秒前 18 秒前に起動 0.0.0.0:6382->6379/tcp redis-6382
396e174a1d92 hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6381->6379/tcp redis-6381
df6ebce6f12a hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6380->6379/tcp redis-6380
1673a7d859ea hakimdstx/nodes-redis:4.0.1 "/usr/local/redis/..." 3 日前 3 日前にアップ 0.0.0.0:6379->6379/tcp redis-6379
[ルート@etcd3 redis]#
[root@etcd3 redis]# docker examine 10c62aafa4da 73e4f843d8cb d9a71dd3f969 396e174a1d92 df6ebce6f12a 1673a7d859ea | grep IPA
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.7",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.7",
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.6",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.6",
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.5",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.5",
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.4",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.4",
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.3",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.3",
            「セカンダリIPアドレス」: null、
            "IPアドレス": "172.17.0.2",
                    "IPAMConfig": null、
                    "IPアドレス": "172.17.0.2",

次のようなことがわかります: redis-6379: 172.17.0.2、redis-6380: 172.17.0.3、redis-6381: 172.17.0.4、redis-6382: 172.17.0.5、redis-6383: 172.17.0.6、redis-6384: 172.17.0.7

Redisの設定
エルト

Redis Clusterのクラスター対応操作

//クラスタ 
CLUSTER INFO クラスター情報を出力します。CLUSTER NODES クラスターに現在認識されているすべてのノードと、これらのノードに関する関連情報を一覧表示します。  
   
//ノード 
CLUSTER MEET <ip> <port> ip と port で指定されたノードをクラスターに追加し、クラスターの一部にします。 
CLUSTER FORGET <node_id> node_id で指定されたノードをクラスターから削除します。 
CLUSTER REPLICATE <node_id> 現在のノードを、node_id で指定されたノードのスレーブとして設定します。 
CLUSTER SAVECONFIG ノードの構成ファイルをハードディスクに保存します。  
   
//スロット 
CLUSTER ADDSLOTS <slot> [slot ...] 現在のノードに 1 つ以上のスロットを割り当てます。 
CLUSTER DELSLOTS <slot> [slot ...] 現在のノードの割り当てから 1 つ以上のスロットを削除します。 
CLUSTER FLUSHSLOTS は、現在のノードに割り当てられているすべてのスロットを削除し、現在のノードをスロットが割り当てられていないノードにします。 
CLUSTER SETSLOT <slot> NODE <node_id> node_id で指定されたノードにスロットを割り当てます。スロットが別のノードに割り当てられている場合は、他のノードでスロットを削除してから割り当てます。 
CLUSTER SETSLOT <slot> MIGRATING <node_id> このノードのスロットを node_id で指定されたノードに移行します。 
CLUSTER SETSLOT <slot> IMPORTING <node_id> node_id で指定されたノードからこのノードにスロットをインポートします。 
CLUSTER SETSLOT <slot> STABLE スロット slot のインポートまたは移行をキャンセルします。  
   
//鍵 
CLUSTER KEYSLOT <key> キーを配置するスロットを計算します。 
CLUSTER COUNTKEYSINSLOT <スロット> スロット slot に現在含まれているキーと値のペアの数を返します。 
CLUSTER GETKEYSINSLOT <スロット> <カウント> count スロット内のキーを返します。 

Redis クラスター認識: ノード ハンドシェイク - クラスター モードで実行されているノードのグループが、ゴシップ プロトコルを介して相互に通信し、お互いを認識するプロセスを指します。

192.168.10.52:6379> クラスターミート 172.17.0.3 6379
わかりました
192.168.10.52:6379> クラスターミート 172.17.0.4 6379
わかりました
192.168.10.52:6379> クラスターミート 172.17.0.5 6379
わかりました
192.168.10.52:6379> クラスターミート 172.17.0.6 6379
わかりました
192.168.10.52:6379> クラスターミート 172.17.0.7 6379
わかりました
192.168.10.52:6379> クラスターノード
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター - 0 1528697195600 1 接続済み
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528697195600 0 接続済み
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 マスター - 0 1528697195600 5 接続済み
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 マスター - 0 1528697194000 4 人が接続中
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 マスター - 0 1528697194995 3 人が接続中
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 自分、マスター - 0 1528697195000 2 人が接続中

6 つのノードがクラスター化されましたが、クラスター ノードにスロットがまだ割り当てられていないため、まだ機能していません。

割り当てスロット情報

172.17.0.2:6379のスロット数を確認する

192.168.10.52:6379> クラスター情報
クラスター状態:失敗
cluster_slots_assigned:0 # 割り当てられたスロットの数は0です
クラスタースロットOK:0
クラスタースロットp失敗:0
クラスタースロット失敗:0
クラスターの既知のノード:6
クラスターサイズ:0
クラスター現在のエポック:5
クラスター_マイ_エポック:2
クラスター統計メッセージping送信:260418
クラスター統計メッセージ送信:260087
クラスター統計メッセージ会議送信:10
クラスター統計メッセージ送信数:520515
クラスター統計メッセージのping受信:260086
クラスター統計メッセージポン受信:260328
クラスター統計メッセージ会議受信:1
クラスター統計受信メッセージ:520415

上記のように、スロットが割り当てられていないため、クラスターのステータスは失敗しています。また、クラスターを使用するには、16384 個のスロットすべてを一度に割り当てる必要があります。

スロットを割り当てる

スロットの割り当て: CLUSTER はスロットを追加します。1 つのスロットは 1 つのノードにのみ割り当てることができます。16384 個のスロットすべてを割り当てる必要があり、異なるノードが競合することはできません。
したがって、スクリプト addslots.sh を使用して割り当てます。

#!/bin/bash
# ノード1 192.168.10.52 172.17.0.2
0件
((i=n;i<=5461;i++)) の場合
する
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6379 -a 123456 クラスターにスロットを追加 $i
終わり
 
 
# ノード2 192.168.10.52 172.17.0.3
5462人
((i=n;i<=10922;i++)) の場合
する
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6380 -a 123456 クラスターにスロットを追加 $i
終わり
 
 
# ノード3 192.168.10.52 172.17.0.4
10923人
((i=n;i<=16383;i++)) の場合
する
   /usr/local/bin/redis-cli -h 192.168.10.52 -p 6381 -a 123456 クラスターにスロットを追加 $i
終わり

このうち、-a 123456 は入力する必要のあるパスワードを示します。

192.168.10.52:6379> クラスター情報
cluster_state:fail # クラスターのステータスが失敗しました cluster_slots_assigned:16101 # 完全に割り当てられていません cluster_slots_ok:16101
クラスタースロットp失敗:0
クラスタースロット失敗:0
クラスターの既知のノード:6
クラスターサイズ:3
クラスター現在のエポック:5
クラスター_マイ_エポック:2
クラスター統計メッセージping送信:266756
クラスター統計メッセージ送信:266528
クラスター統計メッセージ会議送信:10
クラスター統計メッセージ送信数:533294
クラスター統計メッセージのping受信:266527
クラスター統計メッセージポン受信:266666
クラスター統計メッセージ会議受信:1
クラスター統計メッセージが受信されました:533194<br>
192.168.10.52:6379> クラスター情報
cluster_state:ok # クラスターのステータスは成功です cluster_slots_assigned:16384 # すべての割り当てが完了しました cluster_slots_ok:16384
クラスタースロットp失敗:0
クラスタースロット失敗:0
クラスターの既知のノード:6
クラスターサイズ:3
クラスター現在のエポック:5
クラスター_マイ_エポック:2
クラスター統計メッセージping送信:266757
クラスター統計メッセージ送信:266531
クラスター統計メッセージ会議送信:10
クラスター統計メッセージ送信数:533298
クラスター統計メッセージのping受信:266530
クラスター統計メッセージポン受信:266667
クラスター統計メッセージ会議受信:1
クラスター統計受信メッセージ:533198

要約すると、すべてのスロットが割り当てられている場合、クラスターはまだ実行可能です。スロットを削除すると、クラスターはすぐに失敗します。自分で試してみてください - CLUSTER DELSLOTS 0。

高可用性を実現する方法

上記では、完全かつ運用可能な Redis クラスターを構築しましたが、各ノードは単一のポイントです。この方法では、1 つのノードに障害が発生すると、スロットの割り当てが不完全であるため、クラスター全体がクラッシュする可能性があります。そのため、各ノードにレプリカ スタンバイ ノードを構成する必要があります。
すでに 6 つのスタンバイ ノードを事前に作成しています。そのうち 3 つはクラスターの構築に使用されたため、残りの 3 つはスタンバイ レプリカとして直接使用できます。

192.168.10.52:6379> クラスター情報
クラスター状態:正常
割り当てられたクラスタースロット:16384
クラスタースロットOK:16384
クラスタースロットp失敗:0
クラスタースロット失敗:0
cluster_known_nodes:6 # 合計 6 ノード cluster_size:3 # クラスターには 3 つのノードがあります cluster_current_epoch:5
クラスター_マイ_エポック:2
クラスター統計メッセージping送信:270127
クラスター統計メッセージ送信:269893
クラスター統計メッセージ会議送信:10
クラスター統計メッセージ送信数:540030
クラスター統計メッセージping受信:269892
クラスター統計メッセージポン受信:270037
クラスター統計メッセージ会議受信:1
クラスター統計受信メッセージ:539930

すべてのノードIDを表示

192.168.10.52:6379> クラスターノード
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター - 0 1528704114535 1 接続済み 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528704114000 0 接続済み 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 マスター - 0 1528704114023 5 接続済み
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 マスター - 0 1528704115544 4 人が接続中
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 マスター - 0 1528704114836 3 が接続されています
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 自分、マスター - 0 1528704115000 2接続 0-5461

レプリカノードを追加するスクリプトを書く

[root@etcd2 tmp]# vi addSlaveNodes.sh
#!/bin/bash
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6382 -a 123456 クラスターレプリケート 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6383 -a 123456 クラスターレプリケート 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c
 
/usr/local/bin/redis-cli -h 192.168.10.52 -p 6384 -a 123456 クラスターレプリケート f45f9109f2297a83b1ac36f9e1db5e70bbc174ab

注: 1. スタンバイとして使用されるノードには未割り当てのスロットが必要です。そうでない場合、操作は失敗します (エラー) ERR マスターを設定するには、ノードが空で、スロットが割り当てられていない必要があります。
2. 現在のノードを node_id のレプリカ ノードにするには、追加するノードに対して操作 CLUSTER REPLICATE [node_id] を実行する必要があります。
3. スレーブ ノードの追加 (クラスター レプリケーション): レプリケーションの原理は、単一マシンの Redis レプリケーションと同じです。違いは、クラスターの下のスレーブ ノードもクラスター モードで実行する必要があり、レプリケーションの前にクラスターに追加する必要があることです。

すべてのノード情報を表示します:

192.168.10.52:6379> クラスターノード
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター - 0 1528705604149 1 接続 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528705603545 0 接続済み 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 スレーブ f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528705603144 5 接続済み
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 スレーブ 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528705603000 4 台接続
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 スレーブ 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528705603000 3 台接続
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 自分、マスター - 0 1528705602000 2接続 0-5461

これで、3 つのマスターと 3 つのスレーブを持つ高可用性クラスターが実装されたことがわかります。

高可用性テスト - 現在の実行ステータスを表示するためのフェイルオーバー:

192.168.10.52:6379> クラスターノード
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター - 0 1528705604149 1 接続 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528705603545 0 接続済み 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 スレーブ f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528705603144 5 接続済み
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 スレーブ 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528705603000 4 台接続
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 スレーブ 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528705603000 3 台接続
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 自分、マスター - 0 1528705602000 2接続 0-5461

上記は正常に動作しています

マスターをシャットダウンし、ポート 6380 のコンテナを選択して停止してみます。

192.168.10.52:6379> クラスターノード
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター、失敗 - 1528706408935 1528706408000 1 接続 5462-10922
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528706463000 0 接続済み 10923-16383
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 スレーブ f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528706462980 5 接続済み
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 スレーブ 54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 0 1528706463000 4 台接続
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 スレーブ 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528706463985 3 が接続されています
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 自分、マスター - 0 1528706462000 2接続 0-5461
192.168.10.52:6379>
192.168.10.52:6379> クラスター情報
クラスター状態:失敗
割り当てられたクラスタースロット:16384
クラスタースロットOK:10923
クラスタースロットp失敗:0
クラスタースロット失敗:5461
クラスターの既知のノード:6
クラスターサイズ:3
クラスター現在のエポック:5
クラスター_マイ_エポック:2
クラスター統計メッセージping送信:275112
クラスター統計メッセージ送信:274819
クラスター統計メッセージ会議送信:10
クラスター統計メッセージ送信失敗:5
クラスター統計メッセージ送信数:549946
クラスター統計メッセージping受信:274818
クラスター統計メッセージポン受信:275004
クラスター統計メッセージ会議受信:1
クラスター統計メッセージ受信失敗:1
クラスター統計受信メッセージ:549824

上記から、クラスター全体に障害が発生し、スレーブノードがマスターノードに自動的にアップグレードされていないことがわかります。何が起こったのでしょうか? ?
停止したコンテナを再起動し、ログ情報を確認します[root@df6ebce6f12a /]# tail -f /var/log/redis/redis-server.log :

1:S 6月11日 09:57:46.712 # クラスターの状態が変更されました: ok
1:S 11 Jun 09:57:46.718 * (非重大) マスターは REPLCONF リスニング ポートを理解しません: -NOAUTH 認証が必要です。
1:S 11 Jun 09:57:46.718 * (非重大) マスターは REPLCONF 機能を理解しません: -NOAUTH 認証が必要です。
1:S 6月11日 09:57:46.719 * 部分的な再同期は不可能です(キャッシュされたマスターがありません)
1:S 11 Jun 09:57:46.719 # マスターから PSYNC への予期しない応答: -NOAUTH 認証が必要です。
1:S 6月11日 09:57:46.719 * SYNCで再試行しています...
1:S 11 Jun 09:57:46.719 # MASTER はエラーのためレプリケーションを中止しました: NOAUTH 認証が必要です。
1:S 6月11日 09:57:46.782 * MASTER 172.17.0.6:6379に接続中
1:S 6月11日 09:57:46.782 * マスター <-> スレーブ同期が開始されました
1:S 11 Jun 09:57:46.782 * SYNC の非ブロッキング接続によってイベントが発生しました。

ご覧のとおり、マスターとスレーブ間のアクセスには認証が必要です。以前、redis.conf で # masterauth <master-password> を設定するのを忘れたため、マスターとスレーブは通信できません。設定を変更すると、自動フェイルオーバーが正常に機能します。

場合によっては、手動フェイルオーバーが必要になります。

ポート 6380: 6383 のスレーブ ノードにログインし、CLUSTER FAILOVER コマンドを実行します。

192.168.10.52:6383> クラスターフェイルオーバー
(エラー) ERR マスターがダウンしているか故障しています。CLUSTER FAILOVER FORCE を使用してください。

マスターがダウンしているため、強制転送を実行する必要があることがわかりました。

192.168.10.52:6383> クラスターフェイルオーバー強制
わかりました

現在のクラスター ノードのステータスを表示します。

192.168.10.52:6383> クラスターノード
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 スレーブ 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528707535332 3 が接続されています
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 スレーブ f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528707534829 5 接続済み
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528707534527 0 接続済み 10923-16383
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 自分、マスター - 0 1528707535000 6接続 5462-10922
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 マスター - 0 1528707535834 2 接続 0-5461
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 マスター、失敗 - 1528707472833 1528707472000 1 人が接続されています

スレーブ ノードがマスター ノードにアップグレードされました。このとき、ノード 6380 の redis を再起動しようとしました (実際には停止したコンテナを再起動します)。

192.168.10.52:6383> クラスターノード
0bbdc4176884ef0e3bb9b2e7d03d91​​b0e7e11f44 172.17.0.5:6379@16379 スレーブ 760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 0 1528707556044 3 が接続されています
ae86224a3bc29c4854719c83979cb7506f37787a 172.17.0.7:6379@16379 スレーブ f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 0 1528707555000 5 接続済み
f45f9109f2297a83b1ac36f9e1db5e70bbc174ab 172.17.0.4:6379@16379 マスター - 0 1528707556000 0 接続済み 10923-16383
98aebcfe42d8aaa8a3375e4a16707107dc9da683 172.17.0.6:6379@16379 自分、マスター - 0 1528707556000 6接続 5462-10922
760e4d0039c5ac13d04aa4791c9e6dc28544d7c7 172.17.0.2:6379@16379 マスター - 0 1528707556000 2 接続 0-5461
54cb5c2eb8e5f5aed2d2f7843f75a9284ef6785c 172.17.0.3:6379@16379 スレーブ 98aebcfe42d8aaa8a3375e4a16707107dc9da683 0 1528707556547 6 接続済み

ノード 6380 がノード 6383 のスレーブ ノードになっていることがわかりました。

これでクラスターは完了し、クラスターのステータスが復元されているはずです。確認してみましょう。

192.168.10.52:6383> クラスター情報
クラスター状態:正常
割り当てられたクラスタースロット:16384
クラスタースロットOK:16384
クラスタースロットp失敗:0
クラスタースロット失敗:0
クラスターの既知のノード:6
クラスターサイズ:3
クラスター現在のエポック:6
クラスター_マイ_エポック:6
クラスター統計メッセージping送信:19419
クラスター統計メッセージ送信:19443
クラスター統計メッセージ会議送信:1
クラスター統計メッセージ認証要求送信:5
クラスター統計メッセージ更新送信:1
クラスター統計メッセージ送信数:38869
クラスター統計メッセージping受信:19433
クラスター統計メッセージポン受信:19187
クラスター統計メッセージ会議受信数:5
クラスター統計メッセージ受信失敗:4
クラスター統計メッセージ認証確認受信:2
クラスター統計受信メッセージ:38631

はい、問題ありません。

クラスター アクセス クライアントが初期化されるとき、必要なのはノードのアドレスだけです。クライアントはまず、このノードに対して get key などのコマンドを実行しようとします。キーが配置されているスロットがノード上にある場合は、直接正常に実行できます。スロットがノード内にない場合、ノードは MOVED エラーを返し、スロットに対応するノードをクライアントに伝えます。クライアントはノードに移動してコマンドを実行できます。

192.168.10.52:6383> こんにちは
(エラー) 移動 866 172.17.0.2:6379
 
192.168.10.52:6379> 番号 20004 を設定
(エラー) 移動 7743 172.17.0.3:6379

さらに、select コマンドは select 0 をサポートできますが、redis クラスター バージョンでは db0 のみが使用されます。他のすべての db はエラーを返します。

192.168.10.52:6383> 0を選択
わかりました
192.168.10.52:6383> 1を選択
(エラー) ERR SELECT はクラスタモードでは許可されません

最近、一部のネットユーザーから、docker redis クラスター接続エラーの問題について質問がありました。具体的なエラーは次のとおりです。

最初は、すべてのノードが追加されていないことが考えられます。追加した後も、上記の問題は依然として存在します。クロスホストアクセスであると考えると、ルーティングアドレスが見つからないことが原因であるはずです。上記のチュートリアルを書いたとき、Docker はデフォルトのネットワーク モードであるブリッジ モードで動作していました。結局、スタンドアロン アクセスを主眼に置き、ドキュメントの学習と整理が主な目的でした。ただし、実際のアプリケーション シナリオでは、ほとんどの場合、パブリック ネットワークのホスト間アクセスが必要になります。問題は明らかです。ホストのパブリック IP アドレスを共有するようにクラスターを設定する方がよいと思います。したがって、解決策は次のとおりです。

  • Docker の実行中、実行ネットワーク モードは host です。
  • ポート競合の解決。結局、ホスト モードでは、コンテナがホスト マシンのポートを占有します。そのため、構成から開始し、ホスト マシンに redis-60001.conf、redis-60002.conf、redis-60003.conf... という構成を生成します。ポートの数だけファイルを作成し、最後にコンテナを実行して、コンテナに構成をマウントし、ホストの構成を上書きします。

最終的な操作は次のようになります。

docker run -d -name redis -6380 -net host -v /tmp/redis.conf:/usr/local/redis/redis.conf hakimdstx/nodes-redis:4.0.1

この時点で、ネットワークの問題が解決されました。
PS生産環境は、ファイアウォールの問題に注意を払う必要があります。

引用:

1。Redisクラスターの展開、管理、テスト

2。Docker下のRedisのマスタースレーブと永続性構成

これは、Docker Redisクラスターの構築については、Redisクラスターを構築するためのこの記事の終わりです。

以下もご興味があるかもしれません:
  • Dockerは公式のRedis画像をインストールし、パスワード認証を有効にします
  • Docker展開スプリングブートプロジェクト統合アクセスのためのレディス画像サンプルコード
  • DockerでRedis画像を作成する方法
  • DockerにRedisコンテナをインストールするための実装手順
  • 5分でDockerを使ってRedisのクラスターモードとセンチネルモードを構築する方法を教えます
  • DockerはRedis5.0をビルドし、データをマウントします
  • DockerにRedisをインストールして開始する方法を教える5分(新しい方法)
  • Redis イメージの Docker インストールと設定手順

<<:  MySQLシリーズ15 MySQL共通設定とパフォーマンスストレステスト

>>:  Alipay の新しいホームページのフロントエンドの実践的な概要

推薦する

MySQL で制限を使用するとパフォーマンスに影響するのはなぜですか?

まず、MySQL のバージョンについて説明します。 mysql> バージョンを選択します();...

テキストエリアのテキストをHTMLに変換する方法、つまり復帰改行について

説明: テキストエリアの値の改行を新しい行に変更しますコードをコピーコードは次のとおりです。 <...

Linux sshのデフォルトのリモートポート番号を変更する6つの手順

Linux のデフォルトの ssh リモート ポートは 22 です。デフォルトのポートは、悪意のある...

MySQL InnoDB ストレージエンジンのメモリ管理の詳細な説明

目次ストレージエンジンのメモリ管理データ ページを LRU キューの先頭に置かないのはなぜですか?ダ...

deepin20 で NVIDIA クローズドソース ドライバーをインストールするための詳細な手順

ステップ1: ディープ「グラフィックドライバー」をインストールするdeepin v20にはデフォルト...

Dockerコンテナが停止できない問題の解決方法

解決策は次のとおりです。 1. コンテナを強制削除する docker rm -f ジェンキンス2. ...

泡の小さな鋭角効果を実現するCSS

効果画像(境界線の色が薄すぎるので、{} で囲みます): { }参考リンク Pure CSS バブル...

Vue 名前付きスロットの基本的な使用例

序文名前付きスロットは、スロット内の「name」属性を使用して要素にバインドされます。知らせ: 1....

HTML のボタン タグをクリックしてページにジャンプする 3 つの方法

方法1: onclickイベントを使用する <input type="button&...

Javascript 構造化代入の詳細

目次1. 配列の分解2. オブジェクトの分解3. 不完全な解体4. 分割代入を使用して変数交換を実装...

HTMLテーブルタグの詳しい解説(初心者向け)

表> <TR> <TD> <TH> <キャプション&...

私の CSS フレームワーク - base.css (ブラウザのデフォルト スタイルをリセット)

コードをコピーコードは次のとおりです。 @文字セット "utf-8"; /* @...

HTML thead タグの定義と使用法の詳細な紹介

コードをコピーコードは次のとおりです。 <thead> <!– 最初の 2 行をヘ...

MySQL の非主キー自己増分使用例の分析

この記事では、例を使用して、MySQL の非主キーの自己増分の使用方法を説明します。ご参考までに、詳...

MySQL Community Server 5.7.19 インストール ガイド (詳細)

MySQL公式サイトのzipファイルのダウンロードリンク https://dev.mysql.co...