『Redis開発と運営』ノート

7817 ワード

本ノートは『Redis開発と運維』(付磊張益軍著)に由来する.
初対面Redis
単一スレッド高速実行シーン向けのインラインデータベース
とくせい
  • データ構造:string文字列(ビットマップbitmaps,hyperloglog)、hashハッシュテーブル、listリスト、setセット、zset秩序セット
  • 単一スレッドモデル
  • 持続化方式:RDB,AOF
  • マスターコピー
  • データ構造&APIobject encoding testObject:testObject内部エンコーディングの表示zipXxx:よりコンパクトなデータ構造であり、集合要素の総数が少ない(デフォルト512、秩序化集合zsetは128)と、すべての要素が大きくない場合(64 bytes)に採用されます.そうしないと、他の大容量構造を使用します.
    lpush + lpop = stack
    lpush + rpop = queue
    lpush + ltrim =     
    lpush + brpop =      # brpop    
    
    ttl : time to live #     s
    pttl #      ms
    persist #    ,       
    set # string set       
    

    二次データ構造内部要素の期限切れ機能はサポートされていません
    コマンド#コマンド#
    アクティブドメイン
    げんしせい
    複数のキーをサポート
    推奨事項の使用
    move
    Redisインスタンス内部
    はい
    いいえ
    廃棄する
    dump + restore
    Redisインスタンス間
    いいえ
    いいえ
    非原子
    migrate
    Redisインスタンス間
    はい
    はい
    原子、推奨
    シングルスレッドアーキテクチャ
    コマンドがサービス側に到着したら、キュー順に単一スレッドで実行します.
    epoll I/O多重化IO性能向上
    redisが速い理由:
  • 純メモリアクセス
  • I/O多重:epoll
  • 単一スレッドスレッド回避スレッド競合
  • keysフルパスキーはredisブロックを引き起こす可能性があり、ノードから実行するか、漸進的なscanを使用して置き換えることができます(期間中の更新が漏れる可能性があります)
    追加機能
    スロークエリ解析
    スロークエリは、コマンドの実行時間のみを統計し、ネットワーク通信とコマンドキューの時間は統計しません.
    slowlog-log-slower-than : 0      ,<0   ,>0          (  μs),  10000,   100
    slowlog-max-len :      ,      
    

    redis shell
    --bigkeys :   scan      ,           
    --latency/latency-history/dist :       
    --stat:        
    

    pipeline
    Redisコマンドのセットを組み立て、RTT(Round Trip Time往復時間)を1回でRedisに転送し、実行構造を一度にシーケンスで返す
    pipeline非原子操作
    事務とLua
    取引
    watch key #           ,key                
    multi
    cmd...
    exec
    
    discard #    
    

    コマンドが間違っていて、トランザクション実行時エラーが実行されず、実行されたロールバックが実行されず、redisはトランザクションロールバックをサポートしません.
    Lua
    Luaスクリプトは原子のために実行されます
    eval:luaスクリプトを実行するeval key key evalsha:サーバ多重スクリプトevalsha SHA1 key key script kill:実行中のLuaスクリプトを殺す
    bitmaps
    bitmapsは本質的に文字列であり、データ構造ではない.
    HyperLogLog
    HyperLogLogは本質的に文字列であり、データ構造ではない
    独立した合計数の統計は、最小限のメモリ領域で実行できます.
    近似推定、ミス率があり、精度で空間を取り替える
    Redisブロック
  • 測位異常ノードはクライアントconnectionクラスを修正し、接続を専門にキャプチャし、コマンドとプロトコルを送信してイベントの異常を読み取り、対応するip portを印刷し、測位ブロックノード
  • を印刷することができる.
  • 内因性APIまたはデータ構造を調べる不合理なCPU飽和と持続化に関連するブロック
  • を使用する.
    redisメモリ
    哨兵sentinel
    クライアントは初期化時にsentinelセットに接続してmasterノード情報を取得する
    sentinelノード間でデータを共有
    sentinelは複数のプライマリノードを同時に監視できます
  • 各sentinelはデータノードと他のsentinelノードを監視し、ノードが到達できないことを発見した場合、ノードに対してオフライン識別
  • を行う.
  • 下線でmasterノードが識別されている場合、sentinelは他のsentinelノードと協議し、ほとんどのsentinelノードがmasterノードが達成できないと判断した場合、sentinelノードが故障自動転送
  • を完了するように選択する.
    leader sentinel選挙(Raftアルゴリズム):いずれかのsentinelがメインノードの主観的なダウンラインを確認した後、直ちに他のすべてのsentinelノードに投票命令を送信し(送信者sentinelをleaderに設定)、他のノードが同意しなかった場合にのみ要求に同意し、そうでなければ拒否し、max(quorum,sentinels/2+1)個のsentinelノードが成立することに同意しない場合、そうでなければ次の選挙を行う
    zookeeper leader選挙のように本質的に多数投票であり、結果が出ないまま複数回投票する
    # sentinel.conf
    # sentinel     master    ,  master      slave    
    # 2: 1)  2(quorum) sentinel        ,        
    #    2)   max(2,sentinels/2+1)       ,    leader sentinel
    sentinel monitor master-1 10.211.55.10 6381 2
    #   sentinel ping    sentinel       ,  5000ms       
    sentinel down-after-milliseconds master-1 5000
    #         18s
    sentinel failover-timeout master-1 18000
    #        ,      
    sentinel auth-pass master-1 test123
    #       ,    2 slave    master      ,   master    
    sentinel parallel-syncs master-1 2
    

    tips
  • sentinelノードは、同じマシンに配置するべきではありません
  • 奇数sentinelノード
  • クラスタ
    スロットはredisクラスタ管理データの基本単位である
    クラスタモードでは、処理スロットのマスターノードのみが読み書き要求やクラスタスロットなどの重要な情報の維持を担当する.ノードからプライマリノードデータとステータス情報のコピーのみを行う
    Tips
    redis分散ロックの実装
    前提:redis単一スレッド実行
    stringのsetnxとsetxxコマンド:setnxキーが存在しなければ設定に成功しません.setxxキーが存在しなければ設定に成功しません.
    public class RedisTool {
        private static final String LOCK_SUCCESS = "OK";
        //setnx    key  ,         
        private static final String SET_IF_NOT_EXIST = "NX";
        private static final String SET_WITH_EXPIRE_TIME = "PX";
        private static final Long RELEASE_SUCCESS = 1L;
        /**
         *   
         */
        public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
            //requestId:             
            //      ,           ,    
            String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
            if (LOCK_SUCCESS.equals(result)) {
                return true;
            }
            return false;
        }
        /**
         *       
         */
        public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
            //Lua  :      value ,     requestId  ,        (  )
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            //eval()         
            Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
            if (RELEASE_SUCCESS.equals(result)) {
                return true;
            }
            return false;
        }
    }
    

    リファレンスリンク
  • Redis分散ロックの正確な実現方式