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の拡張を避けるようにします.
  • の利点:読み書き分離は、Slaverを増やすことで同時読解能力を向上させることができる.
  • の欠点:Masterの書き込み能力がボトルネックであり、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セグメントの使用には影響しません.
  • の利点:Redisの書き込み操作を複数のノードに割り当て、書き込みの同時能力を向上させ、拡張が簡単である.
  • 欠点:各ノードは相互傍受、高同時データ書き込み、高同時データ読み出しを負担し、作業任務が重い.

  • 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ノードが停止していると考えられる.

    4.スクリプトとyaml


    リファレンスドキュメント

  • docker redisクラスタ構築