Redisの永続化とレプリケーション

13577 ワード

Redisは、オープンソースで優れたメモリベースのkey-valueキャッシュおよび永続化ストレージソリューションとして、レプリケーション機能も提供しています.ここでは、主にRedisの永続化機能とレプリケーション原理について説明します.
redis持続化
redisデータの操作はメモリで完了し、サーバプロセスが終了するとデータが失われます.この問題を解決するために、メモリ内のデータをディスクに保存し、データの損失を回避し、サービスの再起動時にデータをロードし、持続化を実現します.Redisは2つの持続的なスキームを提供します.
  • RDBは、指定された時間間隔でデータセットを実行するインスタントポイントスナップショットを永続化する.
  • AOFは、受信した書き込み操作をサービス側で記録し、サーバの起動時に再生して元のデータセットを再構築します.

  • RDB持続化
    RDB永続化は、周期的スナップショットと同様の方法でsnapshotによって、書き込み動作をバイナリファイルとして記憶する.
    RDBの作成とロード
    クライアントは、saveまたはbgsaveコマンドを使用してスナップショット保存メカニズムを明示的に起動します.
  • SAVE(同期)は、RDBファイルが作成されるまでredisのサーバプロセスをブロックする.
  • BGSAVE(非同期)派生(fork)サブプロセスは新しいRDBファイルを作成し、BGSAVEを受信した当時のデータベース状態を記録し、プロセスは受信したコマンドを処理し続け、サブプロセスはファイルの作成が完了すると親プロセスに信号を送信し、同時に親プロセスはコマンドを処理しながらポーリングによってサブプロセスの信号を受信する.

  • 自動保存間隔BGSAVEは、プライマリ・プロセスをブロックすることなく、データのバックアップを完了することができる.redis.confに複数の自動保存条件を設定することで、1つの条件が満たされると、サーバはBGSAVEコマンドを実行します.
    # redis      ,       :SAVE ""
    SAVE 900 1      #     900       1 
    SAVE 300 10     #     300       10 
    SAVE 60 10000   #     60       10000 
    
    #     
    stop-writes-on-bgsave-error yes  #               
    rdbcompression yes               #       
    rdbchecksum yes                  #     
    dbfilename dump.rdb              #     
    dir /var/lib/redis               #       
    

    RDBファイルの読み込みは一般に自動的であり、redisサーバが起動したとき、redisサーバが再起動したときにRDBファイルの存在が検出されると、redisは自動的にこのファイルを読み込みます.
    サーバがAOF永続化をオンにすると、サーバはAOFファイルを優先的に使用してデータベースの状態を復元します.
    RDBはキー値ペアを保存することによってデータベース状態を記録し、copy on writeのモードを採用し、毎回全量のバックアップである.
    AOF持続化
    インプリメンテーションプロセス
    Redisがデータセットの変更命令を受けるたびにAOFに追加される.Redisを再起動すると、AOFファイルが再生され、データベースの状態が再構築されます.
    書き込み操作が継続して行われるとAOFファイルはますます大きくなることが想像できる.たとえば、カウンタを100回追加すると、データセットには最終値を格納するキーが1つしかありませんが、AOFには100個記録されています.このうち99個のレコードは、現在のステータスを再構築する際に不要です.そこでRedisは,サービスクライアントに影響を及ぼさずにバックグラウンドでAOFを再構築する興味深いメカニズムをサポートする.BGREWRITEAOFを送信するたびに、Redisは現在のメモリ内のデータセットを再構築するために必要な最短コマンドシーケンスを含む新しいAOFファイルに書き込まれます.Redis 2.2のAOFを使用している場合は、BGREWRITEAOFコマンドを時々実行する必要があります.
    ログの書き換えは、スナップショットと同様の書き込み時レプリケーションメカニズムを採用しています.プロセスは次のとおりです.
  • Redisはfork()を呼び出してサブプロセスを作成する.
  • サブプロセスは、AOFを一時ファイルに書き込むことを開始する.
  • 親プロセスは、メモリバッファに新しい変更を蓄積します(古いAOFファイルに新しい変更を書き込むので、書き換えに失敗しても安全です).
  • サブプロセスがファイルの書き換えを完了すると、親プロセスは信号を受信し、サブプロセスが作成したファイルの最後にメモリバッファを追加します.
  • Redisは、古いファイルを新しいAOFファイルとして自動的に名前を変更し、新しいデータを新しいファイルに追加します.

  • 関連オプション
    #AOF   RDB                 。  
    #  AOF  ,  redis      AOF  ,             。 
    appendonly yes
    
    #          。(   appendonly.aof)  
    # appendfilename appendonly.aof 
    
    #redis           :  
    #  
    # no:   ,                        。  。  
    # always:                。 ,     。
    # everysec:       ,    。
    appendfsync everysec  
    
    #    yes  rewrite        fsync,       , rewrite      .                    'yes'。     'no'        。
    no-appendfsync-on-rewrite no  
    
    #         。  
    # redis         ‘BGREWRITEAOF’       ,               。  
    #   AOF             AOF        ,            。
    auto-aof-rewrite-percentage 100  
    #   AOF                ,      Reids                。
    auto-aof-rewrite-min-size 64mb
    

    AOFとRDBの相互作用
    Redis 2.4以降のバージョンでは、RDBスナップショット操作の実行中にAOF書き換えをトリガすることは許されず、AOF書き換え実行中にBGSAVEを実行することも許されない.これにより、2つのRedisバックグラウンドプロセスが同時にディスクに対して煩雑なIO操作を行うことを防止します.スナップショットの実行中に、BGREWRITEAOFを使用してログの書き換え操作を明示的に要求すると、サーバはOKステータスコードに返信し、スナップショットが完了するまでこの操作がスケジュールされていることをユーザーに伝え、書き換えを開始します.
    RedisはAOFとRDBを同時にオンにして再起動し、AOFファイルを使用して元のデータセットを再構築します.通常、AOFファイルはデータの保存が最も完全であるためです.
    redisレプリケーション
    レプリケーション・テクノロジーにより、データベースの読み書き操作を異なるCPU上で実行される独立したサーバに分散させ、データ冗長性を実現できます.Redisのレプリケーション(replication)は、非常に簡単に使用および構成されたマスタースレーブレプリケーションであり、Redisがサーバからプライマリサーバの正確なコピーになることを可能にする.
    レプリケーションの実装
    redisは、1台の物理マシンが複数のサービスを起動して実装することをサポートします.今回のインスタンスは、1台の物理マシンで実装されます.masterインスタンスを起動します.
    # master  
    /usr/bin/redis-server --port 8000 &
    
    # slave   
    /usr/bin/redis-server --port 8001 --slaveof 127.0.0.1 8000 &
    /usr/bin/redis-server --port 8002 --slaveof 127.0.0.1 8000 &
    /usr/bin/redis-server --port 8003 --slaveof 127.0.0.1 8000 &
    
    #     
    ss -tnl 
    
    LISTEN      0      128       *:8000                  *:*                  
    LISTEN      0      128       *:8001                  *:*                  
    LISTEN      0      128       *:8002                  *:*                  
    LISTEN      0      128       *:8003                  *:*  

    これにより、4台のRedisインスタンスを正常に起動し、masterインスタンスのサービスポートは8000、R 1、R 2、R 3のサービスポートはそれぞれ8001、8002、8003であり、クラスタ図は以下の通りである.
    レプリケーションプロセス
    上の図は、Redisレプリケーションの作業手順です.
  • slaveはsyncコマンドをmasterに送信します.
  • masterは、サブプロセスを開いてrdbファイルにdatasetを書き込み、サブプロセスが完了する前に受信した書き込みコマンドをキャッシュします.
  • サブプロセスが書き終わり、親プロセスはRDBファイルのslaveへの送信を開始することを知った.
  • masterはRDBファイルを送信し、キャッシュされたコマンドもslaveに送信します.
  • masterインクリメンタル書き込みコマンドをslaveに送信します.

  • 同期はコマンドフローによって行われ,Redisのプロトコルと同じフォーマットである.Redisのポートをtelnetで接続し、SYNCコマンドを送信すると、masterはメッセージに応答します.
    [root@node3 ~]# telnet  127.0.0.1 8000 
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    SYNC            #   SYNC  
    $77
    REDIS0007   redis-ver3.2.10
    redis-bits????e?Lused-mem?X?\eRXshell*1
    $4
    PING
    

    ぶぶんさいどうき
    プライマリ・スレーブ・リンクが何らかの理由で切断された場合、スレーブ・サーバは自動的に再接続できます.プライマリ・サーバが複数の同時スレーブ・サーバから同期要求を受信した場合、すべてのスレーブ・サーバにサービスを提供するために1つのバックグラウンド保存のみが実行されます.Redis 2.8から、レプリケーション・リンクが切断された後、完全な再同期を必要とせずに、サーバからプライマリ・サーバに再接続するときにレプリケーション・プロセスを継続できます.
    マスターはRDBファイルのバックアップに加えて、ループキューとループキューの書き込みインデックスとslave同期のグローバルoffsetを維持します.ループキューは最新の操作データを格納するために使用されます.slaveとmasteが再接続されていない場合、slaveメンテナンスのoffset、つまり前回どこに同期したかという値をマスターに伝えます.同時に、マスターに前回現在のslaveに接続したマスターのrunidを伝え、次の2つの条件を満たします.Redisはフルコピーされません:
  • slaveによって伝達されるrun idはmasterのrun idと一致する.
  • masterは、リングキュー上で対応するoffset値を見つけることができる.

  • 上記の2つの条件を満たすと、Redisはフルコピーされません.このようなメリットは、パフォーマンスを大幅に向上させ、無効な仕事をしないことです.
    レプリケーションはpsyncコマンドによって実現され、slaveはpsyncコマンドによってRedisをインクリメンタルレプリケーションすることができ、もちろん最終的にインクリメンタルレプリケーションできるかどうかは、リングキューのサイズとslaveの断線時間の長さと再接続されたこのmasterが以前のmasterであるかどうかにかかっている.
    関連パラメータの設定
    
    repl-backlog-size 1mb      #       
    repl-backlog-ttl 3600      #   slave       ,          
    repo-diskless-sync no      #    Diskless Replication(    )     
    repl-diskless-sync-delay 5 #            

    サーバから読み取り専用
    Redis 2.6からは、デフォルトでオンになっている読み取り専用モードがサーバからサポートされます.この行為はredisによって行われた.confファイルのslave-read-onlyオプション制御は、実行時にCONFIGSETを使用してオンまたはオフにできます.このような特性は、DEBUGやCONFIGのような管理コマンドなどがまだ利用可能であるため、サーバからインターネットに露出することを意味するものではありません.しかしredisではconfではrename-commandコマンドを使用してコマンドを禁止します.これらの書き込みデータは、サーバとプライマリ・サーバが再同期されたとき、またはサーバが再起動されたときに破棄されます.また、サーバから書き込み可能な合理的なシーンに短いデータが格納されています.たとえば、プライマリ・サーバが故障し、他のノードがプライマリ・サーバとして必要になった場合.
    はんどうきふくせい
    Redis 2.8から、Redisプライマリ・サーバが現在少なくともN個のスレーブ・サーバからの接続を持っている場合に、書き込み要求を受け入れるように設定することができる.MySQLレプリケーションポリシーと少し似ていますが、Redisレプリケーション自体は非同期ですが、半同期レプリケーションポリシーも提供されています.半同期レプリケーションポリシーはRedisレプリケーションにおける意味は次のとおりです.
  • Redisは、サーバから1秒あたりのpingプライマリサーバから、処理済みのレプリケーションストリームのデータ量を報告する.
  • Redisプライマリサーバは、サービスからpingが受信された最後の時間を記録する.
  • ユーザは、最小スレーブサーバ数を構成することができ、各スレーブサーバは最大秒数以下のヒステリシス(lag)を有する.

  • このプロパティには2つの構成パラメータがあります.
    min-slaves-to-write <number of slaves>   # N   
    min-slaves-max-lag <number of seconds>   #       
    N秒未満の少なくともM個の遅延スレーブサーバがある場合、書き込み要求は受け入れられる.このCAP理論のような緩やかなバージョンのCは、指定された書き込みの一貫性を保証することはできませんが、少なくともデータ損失の時間ウィンドウは指定された秒数に制限されています.条件が満たされていない場合、プライマリ・サーバはエラーを返し、書き込み要求は受け入れません.
    リファレンス
    馬哥運維ノート浅析Redis複製redis公式ドキュメント