サーバー開発の要点-[データベース] Redisクラスター

センチネルモード

バックグラウンド

マスターサーバーがダウンした場合、スレーブサーバーを手動でマスターサーバーに切り替える必要があります。これには、手作業による介入が必要であり、面倒で面倒であり、サービスが一定期間利用できなくなります。これは推奨される方法ではありません。多くの場合、センチネルモードを優先します。

定義

Sentinel(Sentinel)は、Redisの高可用性ソリューションです。1つ以上のSentinelインスタンスで構成されるSentinelシステムは、任意の数のマスターサーバーと、これらのマスターサーバーの下にあるすべてのスレーブサーバーを監視し、オフライン時に監視対象のマスターサーバーに入ることができます。 、オフラインマスターサーバーの下のスレーブサーバーは、新しいマスターサーバーに自動的にアップグレードされます。

å¨åµçå¬å¨åµçå¬

 

 

 

server1æé

server1ä¸çº¿ï¼server2å级为æ°ç主æå¡å¨

実際の構成

1.最初にRedisマスタースレーブサーバーを構成し、redis.confファイルを次のように変更します

# 使得Redis服务器可以跨网络访问
bind 0.0.0.0
# 设置密码
requirepass "123456"
# 指定主服务器,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
slaveof 192.168.11.128 6379
# 主服务器密码,注意:有关slaveof的配置只是配置从服务器,主服务器不需要配置
masterauth 123456
复制代码

上記の内容は主にRedisサーバーを構成するためのものであり、スレーブサーバーにはマスターサーバーよりも1つ多いslaveof構成とパスワードがあります。

  1. 3つの歩哨を構成し、各歩哨の構成は同じです。Redisインストールディレクトリにsentinel.confファイルがあります。変更のためにコピーをコピーしてください
# 禁止保护模式
protected-mode no
# 配置监听的主服务器,这里sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,192.168.11.128代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
sentinel monitor mymaster 192.168.11.128 6379 2
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster 123456
复制代码
  1. 上記の変更により、Redisインストールディレクトリのsrcディレクトリに入り、次のコマンドを使用してサーバーと監視を起動できます。
# 启动Redis服务器进程
./redis-server ../redis.conf
# 启动哨兵进程
./redis-sentinel ../sentinel.conf
复制代码

起動シーケンスに注意してください。最初はホスト(192.168.11.128)のRedisサービスプロセスであり、次にスレーブのサービスプロセスが開始され、最後に3つの歩哨のサービスプロセスが開始されます。

記事の理解について質問がある場合は、私にqunを追加してください:議論するために飛び込んください

C / C ++ Linuxサーバー開発の高度なアーキテクチャアーキテクチャの学習資料についてもっと共有します。コンテンツの知識ポイントには、Linux、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、ストリーミングメディア、CDN、P2P、K8S、Docker、TCP / IP、 Coroutine、DPDKなど。VX公式アカウントに従う:Linuxサーバー

ラーニングビデオリンクをクリックしますC / C ++ Linuxサーバー開発/ Linuxバックグラウンド開発アーキテクト-ラーニングビデオ

 

 

集まる

クラスタを設定するには、次の3つの手順が必要です。

1.ノードを準備します

Redisクラスターは通常、複数のノードで構成され、完全で可用性の高いクラスターを確保するために、ノードの数は少なくとも6つです。クラスターモードで実行するようにRedisを構成するには、各ノードでクラスター対応のyesを有効にする必要があります。クラスター内のすべてのノードに統合されたディレクトリを用意することをお勧めします。通常、構成、データ、およびログ関連のファイルをそれぞれ格納するconf、data、およびlogの3つのディレクトリに分割されます。6つのノードの構成をconfディレクトリに置きます

#节点端口
port 6379
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位毫秒
cluster-node-timeout 15000
# 集群内部配置文件
cluster-config-file "nodes-6379.conf"
复制代码

その他の構成はスタンドアロンモードと同じです。構成ファイルの命名規則はredis- {port} .confです。構成の準備ができたら、すべてのノードを起動します。コマンドは次のとおりです。

redis-server conf/redis-6379.conf
redis-server conf/redis-6380.conf
redis-server conf/redis-6381.conf
redis-server conf/redis-6382.conf
redis-server conf/redis-6383.conf
redis-server conf/redis-6384.conf
复制代码

2.ノードハンドシェイク

ノードハンドシェイクとは、クラスターモードで実行されているノードのグループが、ゴシッププロトコルを介して相互に通信し、相互の認識に到達するプロセスを指します。ノードハンドシェイクは、クラスターが相互に通信するための最初のステップです。クライアントは次のコマンドを開始します。clustermeet{ip} {port}

 

図で実行されるコマンドは次のとおりです。clustermeet127.0.0.16380は、ノード6379とノード6380にハンドシェイク通信を実行させます。cluster meetコマンドは非同期コマンドであり、実行後すぐに戻ります。ターゲットノードとのハンドシェイク通信を内部的に開始します。

127.0.0.1:6379>cluster meet 127.0.0.1 6381
127.0.0.1:6379>cluster meet 127.0.0.1 6382
127.0.0.1:6379>cluster meet 127.0.0.1 6383
127.0.0.1:6379>cluster meet 127.0.0.1 6384
复制代码

最後に、cluster nodesコマンドを実行して、6つのノードが相互に認識し、クラスターを形成していることを確認します。

127.0.0.1:6379> cluster nodes
4fa7eac4080f0b667ffeab9b87841da49b84a6e4 127.0.0.1:6384 master - 0 1468073975551
5 connected
cfb28ef1deee4e0fa78da86abe5d24566744411e 127.0.0.1:6379 myself,master - 0 0 0 connected
be9485a6a729fc98c5151374bc30277e89a461d8 127.0.0.1:6383 master - 0 1468073978579
4 connected
40622f9e7adc8ebd77fca0de9edfe691cb8a74fb 127.0.0.1:6382 master - 0 1468073980598
3 connected
8e41673d59c9568aa9d29fb174ce733345b3e8f1 127.0.0.1:6380 master - 0 1468073974541
1 connected
40b8d09d44294d2e23c7c768efc8fcd153446746 127.0.0.1:6381 master - 0 1468073979589
2 connected
复制代码

ノードがハンドシェイクを確立した後、クラスターは正常に動作できなくなります。この時点では、クラスターはオフラインであり、すべてのデータの読み取りと書き込みが禁止されています。

3.配布スロット

Redisクラスターはすべてのデータを16,384スロットにマップします。各キーは固定スロットにマップされ、ノードにスロットが割り当てられている場合にのみ、これらのスロットに関連付けられているキーコマンドに応答できます。cluster addlotsコマンドを使用して、ノードにスロットを割り当てます。ここでは、bash機能を使用して、スロットをバッチで設定します(スロット)

redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0...5461}
redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462...10922}
redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923...16383}
复制代码

クラスターのスケーリング、フェイルオーバー、ノード通信などに関する知識。「Redisの開発と運用および保守」を参照してください

キャッシュの設計

浸透の最適化

キャッシュペネトレーションとは、まったく存在しないデータをクエリすることです。キャッシュレイヤーもストレージレイヤーもヒットしません。通常、フォールトトレランスのために、ストレージレイヤーからデータが見つからない場合、データはキャッシュレイヤーに書き込まれません。 。プロセス全体は、次の3つのステップに分かれています。

1.キャッシュレイヤーが欠落しています。2.ストレージレイヤーが欠落し、空の結果をキャッシュに書き戻しません。3.空の結果を返します

解決

1.空のオブジェクトをキャッシュするストレージレイヤーが失われた後も、空のオブジェクトはキャッシュレイヤーに保持されます。後でこのデータにアクセスできるようになるため、バックエンドのデータソースが保護されます。

ç¼å空å¼åºå¯¹ç©¿éé®é¢

 

空のオブジェクトのキャッシュには2つの問題があります。1つは、空の値がキャッシュされることです。つまり、より多くのキーがキャッシュレイヤーに格納され、より多くのメモリスペースが必要になります(攻撃の場合、問題はより深刻になります)。効果的な方法このタイプのデータの有効期限を短く設定し、自動的に削除することです。

第2に、キャッシュレイヤーとストレージレイヤーのデータは一定期間一貫性がなく、ビジネスに一定の影響を与える可能性があります。たとえば、有効期限は5分に設定されています。この時点でストレージ層がこのデータを追加すると、この期間中にキャッシュ層とストレージ層のデータの間に不整合が生じます。このとき、メッセージシステムまたはその他の方法キャッシュレイヤーの空きスペースをクリアするために使用できます。オブジェクト。

あなたは記事の理解について質問がある場合は、追加してください私はqun:ジャンプの 中で議論します

C / C ++ Linuxサーバー開発の高度なアーキテクチャアーキテクチャの学習資料についてもっと共有します。コンテンツの知識ポイントには、Linux、Nginx、ZeroMQ、MySQL、Redis、fastdfs、MongoDB、ZK、ストリーミングメディア、CDN、P2P、K8S、Docker、TCP / IP、 Coroutine、DPDKなど。VX公式アカウントに従う:Linuxサーバー

ラーニングビデオリンクをクリックしますC / C ++ Linuxサーバー開発/ Linuxバックグラウンド開発アーキテクト-ラーニングビデオ

 

同様のコードは次のように実装されます。

String get(String key) {
// 从缓存中获取数据
String cacheValue = cache.get(key);
// 缓存为空
if (StringUtils.isBlank(cacheValue)) {
    // 从存储中获取
    String storageValue = storage.get(key);
    cache.set(key, storageValue);
    // 如果存储数据为空,需要设置一个过期时间(300秒)
    if (storageValue == null) {
      cache.expire(key, 60 * 5);
    }
    return storageValue;
} else {
    // 缓存非空
    return cacheValue;
  }
}
复制代码

2.ブルームフィルターの傍受

Bloomfilterは、要素がコレクションに存在するかどうかをすばやく判断するために使用されるハッシュセットに似ています。その典型的なアプリケーションシナリオは、キーがコンテナに存在するかどうかをすばやく判断し、存在しない場合は直接返すことです。ブルームフィルターの鍵は、ハッシュアルゴリズムとコンテナーのサイズにあります。最初に、単純な実装の効果を見てみましょう。ここでは、guavaによって実装されたブルームフィルターを使用します。

<dependencies>  
     <dependency>  
         <groupId>com.google.guava</groupId>  
         <artifactId>guava</artifactId>  
         <version>23.0</version>  
     </dependency>  
</dependencies>  
复制代码
public class BloomFilterTest {
 
    private static final int capacity = 1000000;
    private static final int key = 999998;
 
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity);
 
    static {
        for (int i = 0; i < capacity; i++) {
            bloomFilter.put(i);
        }
    }
 
    public static void main(String[] args) {
        /*返回计算机最精确的时间,单位微妙*/
        long start = System.nanoTime();
 
        if (bloomFilter.mightContain(key)) {
            System.out.println("成功过滤到" + key);
        }
        long end = System.nanoTime();
        System.out.println("布隆过滤器消耗时间:" + (end - start));
        int sum = 0;
        for (int i = capacity + 20000; i < capacity + 30000; i++) {
            if (bloomFilter.mightContain(i)) {
                sum = sum + 1;
            }
        }
        System.out.println("错判率为:" + sum);
    }
}
复制代码
成功过滤到999998
布隆过滤器消耗时间:215518
错判率为:318
复制代码

100wデータでは約0.2ミリ秒でキーが一致することがわかります。これは十分に高速です。次に、ブルームフィルターに存在しない1wキーをシミュレートしたところ、一致エラー率は318/10000、つまりエラー率は約3%でした。ブルームフィルターのソースコードに従って、デフォルトであることがわかりました。エラー許容率は0.03でした:

public String getByKey(String key) {
    // 通过key获取value
    String value = redisService.get(key);
    if (StringUtil.isEmpty(value)) {
        if (bloomFilter.mightContain(key)) {
            value = userService.getById(key);
            redisService.set(key, value);
            return value;
        } else {
            return null;
        }
    }
    return value;
}
复制代码

雪崩の最適化

キャッシュレイヤーは多数のリクエストを伝送するため、ストレージレイヤーを効果的に保護しますが、何らかの理由でキャッシュレイヤーがサービスを提供できない場合、すべてのリクエストがストレージレイヤーに到達し、ストレージレイヤーへの呼び出し量が増加します。急激に、ストレージレイヤーのダウンタイムもカスケードします。英語でのキャッシュアバランシェの本来の意味は、群れ(実行中のバイソン)のスタンプです。つまり、キャッシュレイヤーがダウンした後、トラフィックは実行中のバイソンのようになり、バックエンドストレージに到達します。

 

キャッシュアバランシェの問題を防止および解決するために、次の3つの側面から始めることができます。

1.キャッシュレイヤーサービスの高可用性を確保します。飛行機に複数のエンジンがあるのと同じように、キャッシュレイヤーが高可用性になるように設計されている場合、個々のノード、個々のマシン、またはコンピュータールームがダウンしていても、サービスを提供できます。たとえば、RedisSentinelとRedisClusterについて説明します。以前に高可用性を達成しました

2.バックエンド電流を制限および劣化させるために、絶縁コンポーネントに依存します。

キャッシュ層であろうとストレージ層であろうと、エラーが発生する可能性があり、リソースと見なすことができます。同時実行性が高いシステムとして、リソースが利用できない場合、このリソースですべてのスレッドがブロック(ハング)し、システム全体が利用できなくなる可能性があります。ダウングレードメカニズムは、同時実行性の高いシステムで非常に一般的です。たとえば、レコメンデーションサービスでは、パーソナライズされたレコメンデーションサービスが利用できない場合、フロントエンドページが天窓を開きます。Java依存関係分離ツールHystrixを推奨する

3.事前に練習します。プロジェクトが稼働する前、キャッシュレイヤーがダウンした後、アプリケーションとバックエンドのロード状況と発生する可能性のある問題がドリルされ、これに基づいていくつかの事前計画設定が行われます。

おすすめ

転載: blog.csdn.net/Linuxhus/article/details/114176056