Redisの詳細説明(redisスレッドモード、データ永続化機構、マスタースレーブレプリケーション、キャッシュ侵入、キャッシュブレイクダウンなど)

1.redisの概要

Redis は、主にデータベース、キャッシュ、およびメッセージ ミドルウェアとして使用され、複数の言語をサポートし、メモリベースのキー値データ構造ストレージ システムです。

Redis はデータの永続性をサポートしています。これにより、メモリ内のデータをディスクに保存し、再起動時に使用するために再度読み込むことができます。

Redis はキーと値のデータ構造をサポートするだけでなく、リスト、セット、ハッシュ、およびその他のデータ構造もサポートします。

Redis はデータ バックアップ、つまりマスター スレーブ (マスター スレーブ) モードでのデータ バックアップをサポートしています。

2.Redisスレッドモデル

redis6.x より前は、完全にシングル スレッドであり、外部で提供されるキー値ストレージ サービスもシングル スレッドでした. ネットワーク IO 全体とデータの読み取りおよび書き込み操作は、単一のスレッドによって完了されました.

redis6.x の後に導入されたマルチスレッド化は、マルチスレッド化されたネットワーク リクエストを指しますが、データの読み取りと書き込みの読み取り操作と書き込み操作は依然としてシングルスレッドであるため、redis は同時に安全です。

では、なぜ redis はシングルスレッド実行でこれほど高速なのでしょうか?

1.Redisはメモリ操作を基本としており、すべての操作はメモリレベルであり、検索と操作の時間計算量はO(1)であるため、CPUはredisのボトルネックにならないため、そのパフォーマンスは比較的高いです。

2. 基礎となるデータ構造は単純で、ハッシュ テーブルであり、検索と操作の時間の複雑さは O(1) です。

3. Redis は、I/O 多重化を使用して複数のソケット接続クライアントをリッスンします. 複数の状況を処理するスレッドであり、スレッド切り替えによるオーバーヘッドを削減し、I/O ブロッキング操作を回避し、redis のパフォーマンスを大幅に改善しました

4. シングルスレッド モデルのため、不要なコンテキストの切り替えやマルチスレッドの競合が回避されます。

グローバル ハッシュ テーブル:

Hash は O(1) 時間でハッシュ値を計算し、対応するエントリ位置を見つけることができます. エントリ内にはキー ポインタと値ポインタがありますが、他の情報があります. これが、redis のパフォーマンスが高い理由の 1 つです。

3. redis 永続化

Redis はインメモリ データベースであり、データはメモリに保存されますが、メモリ内のデータは急速に変化し、失われやすいことは誰もが知っています。Redis は永続化メカニズム、つまり RDB (Redis データベース) と AOF (追加のみのファイル) も提供します。

redis をインストールすると、すべての設定が redis.conf ファイルに保存されます。このファイルには、RDB と AOF の 2 つの永続化メカニズムのさまざまな設定が保存されます。特定の条件が満たされると、Redis はメモリ内のデータのスナップショットを自動的に作成し、それをハードディスクに永続化します。

1.RDB方式

Rdb 永続化は、メモリ内のデータ セットのスナップショットを指定された時間間隔内にディスクに書き込むことであり、これは既定の永続化方法でもあります.この方法は、メモリ内のデータをバイナリ ファイルの形式で書き込みます.デフォルトのファイル名は dump.rdb です。redis.conf には、クイック スナップショットをトリガーする条件があります。

構成は次のとおりです。 save 900 1: 少なくとも 1 つのキーが 900 秒以内に変更された後、スナップショットが取得されることを示します。

save 300 10 : 300 秒以内に少なくとも 10 個のキーが変更された後、スナップショットが作成されることを示します。

save 60 10000 : 少なくとも 10000 個のキーが 60 秒以内に変更され、その後スナップショットが作成されることを示します。

redis クライアント モードでは、shutdown save コマンドを使用して、redis サービスをシャットダウンするときにスナップショットを保存します。

redis サービスを再起動するときに、dump.rdb ファイルの内容を復元します。

2.AOF法

ログの形式で各書き込み操作を記録し、Redis によって実行されたすべての命令を記録します (読み取り操作は記録されません)。ファイルを追加するだけで、ファイルを書き換えません。つまり、redis を再起動すると、ログ ファイルの内容に従って書き込みコマンドが前から実行され、データ復旧作業が完了します。

appendfsync 常に #すべての変更が同期され、パフォーマンスが消費されます

appendfsync everysec #1 秒ごとに同期を実行します。この 1 秒のデータが失われる可能性があります (デフォルト)

定期的に mysql と組み合わせて、人工的に mysql に定期的にデータを書き込む

4.Redis トランザクション

Redis トランザクションは、複数のコマンドが同じトランザクション内で確実に実行されるようにするために、複数のコマンドをキューに入れて実行することです。

他のクライアントの影響を受けません。

Redis トランザクション操作:

マルチオープントランザクション

注文1

注文 2

コマンド 3 は、コマンドをキューに追加し、すぐには実行しません。

exec トランザクションを実行

ただし、トランザクションは、同じトランザクション内で複数のコマンドを実行するアトミック性を保証するものではなく、コマンドにエラーが発生してもキューに追加され、実行エラーが他のコマンドの実行に影響を与えることはありません。

redisTemplate.multi();开启事务
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set();
        valueOperations.set();
        valueOperations.set();
     redisTemplate.exec();执行事务

5. マスター/スレーブ レプリケーション

ある Redis サーバーのデータを他の Redis サーバーにコピーすることを指します。前者をマスターノード(master)、後者をスレーブノード(slave)と呼び、データの複製は一方向で、マスターノードからスレーブノードへのみ可能です。1 つの Redis インスタンスをマスターとして使用し、残りをバックアップとして使用します。マスターとバックアップのデータはまったく同じで、マスターはデータの書き込みや読み取りなどのさまざまな操作をサポートし、スレーブはマスターとのデータの同期と読み取りのみをサポートします。つまり、クライアントはマスターにデータを書き込むことができ、マスターはデータの書き込み操作をスレーブに自動的に同期させます。マスター/スレーブ モードは、データ バックアップの問題を非常にうまく解決します。マスター/スレーブ サービス データはほぼ一貫しているため、データを書き込むためのコマンドをマスターに送信して実行することができ、データを読み取るためのコマンドをマスターに送信することができます。実行のための異なるスレーブ. 読み取りと書き込みの分離の目的を達成するため.

期間中に 1 つのサーバーに問題が発生しても、他の redis サービスは正常に動作し、問題のあるサービスに障害が発生した場合でも、クラスター内で引き続き動作することができます。

その場合、Redis マスター/スレーブ レプリケーションのセキュリティを実現するには、データの冗長性とサーバーの冗長性の問題は避けられません。

マスター/スレーブ レプリケーションの機能は次のとおりです。

負荷分散:マスター/スレーブ レプリケーションに基づいて、読み取り/書き込みの分離と組み合わせることで、マスター ノードは書き込みサービスを提供でき、スレーブ ノードは読み取りサービスを提供できます (つまり、Redis データの書き込み時にアプリケーションがマスター ノードに接続します)。 、および Redis データの読み取り時にアプリケーションがスレーブ ノードに接続する) 、サーバーの負荷を共有する; 特に書き込みを減らして読み取りを増やすシナリオでは、複数のスレーブ ノードを介して読み取り負荷を共有することで、Redis サーバーの同時実行性を大幅に向上させることができます。

高可用性 (クラスター) の基礎:上記の機能に加えて、マスター スレーブ レプリケーションはセンチネルとクラスターの実装の基礎でもあるため、マスター スレーブ レプリケーションは Redis の高可用性の基礎です。

redis主从集群不提供容错和恢复的功能, 一旦主节点挂了, 不会自动选取出新的master, 导致客户端所有的写请求都失败, 所以redis提供了哨兵机制, 解决了恢复的功能,但是存在在线扩容的问题, 于是就有了第三种集群方式---redis cluster

redis cluster

实现了redis分布式存储, 也就是每一个节点存储不同的数据, 实现数据分片的功能, 在redis cluster中引入了slot槽, 来实现数据分片, slot的整体取值范围为0----16383, 每个节点会分配一个slot空间, 当我们存取key的时候, redis会根据key计算一个slot值, 找到对应节点进行数据读写操作. 从集群架构来说, redis cluster是一个多主多从的集群, 只有在redis服务器宕机之后在会工作.

哨兵机制:

哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。

它可以通过一套选举机制,在多台从机中选取一台作为主机, 当主机故障恢复后,临时主机又变为从机角色.

六.Key 过期策略

1. 立即删除。在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作。立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对 cpu 是最不友好的。因为删除操作会占用 cpu 的时间.

2. 惰性删除。惰性删除是指,某个键值过期后,此键值不会马上被删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。所以惰性删除的缺点很明显:浪费内存。dict 字典和 expires 字典都要保存这个键值的信息。

3. 定时删除。每隔一段时间,对 expires 字典进行检查,删除里面的过期键。可以看到,第二种为被动删除,第一种和第三种为主动删除,且第一种实时性更高。每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对 cpu 的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。

redis 使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用。

七.缓存穿透、缓存击穿、缓存雪崩

首先看一下缓存处理流程:

1.缓存穿透

我们要查询的数据在数据库中本身就是不存在的, 那么redis中也是不存在的, 每次查询的请求都会直接进入到数据库中.

2.缓存击穿

前提是数据库中有数据, 在某个时间点上, 热点key过期了, 而这时有大量的请求, 如果没有任何的限制, 全都进入到redis中,但是redis中的key已经过期, 所有的请求都会直接进入到数据库中, 导致mysql被压垮

解决的方法:

1.合理的设置过期的时间

2.加锁, redis中如果为空, 等第一个请求的数据进入到缓冲池中时, 再让其他请求从缓存中获取数据.

3.缓存雪崩

大量的key过期,或者缓存出现故障,导致大量的请求到达mysql

解决办法:

1.设置随机过期时间

2.把热点key,放在不同的从机

3.设置不过期

4.定时任务,将快过期的key,重新放入到缓存

对于“Redis 宕机,请求全部走数据库”这种情况,我们可以有以下的思路:

事发前:实现 Redis 的高可用(主从架构+Sentinel(哨兵),尽量避免 Redis挂掉这种情况发生。

事发中:万一 Redis 真的挂了,我们可以设置本地缓存(ehcache)+限流,尽量避免我们的数据库被干掉(起码能保证我们的服务还是能正常工作的)

事发后:redis 持久化,重启后自动从磁盘上加载数据,快速恢复缓存数据。

おすすめ

転載: blog.csdn.net/weixin_71243923/article/details/129779151
おすすめ