redisの包括的な分析

1. redisとは何ですか?

Redisは、メモリに基づくKey-Value NoSqlデータベースであり、ハードディスクに永続化できます。String、List、Set、ZSet、Hashなどの5つのデータ型をサポートします。シングルスレッド、シングルプロセスであり、速度が非常に速いため(Redisの読み取り速度は110,000回/秒、書き込み速度は81000回/秒)、同時操作をサポートしていません。したがって、マクロと呼ぶこともできます。パラレルおよびマイクロシリアル。

2.スタンドアロンおよびクラスター構築

2.1スタンドアロンバージョン(入門的な学習と使用のみ)

環境への準備:centos7、redis-4.0.10.tar.gz①
ファイアウォールをオフにします

systemctl stop firewalld
systemctl disable firewalld

②redis環境の依存関係をインストールします

yum install gcc

③パッケージを解凍します

tar -zxf  redis-4.0.10.tar.gz

④解凍したフォルダに入り、コンパイルします

[root@localhost redis-4.0.10]# make

⑤redis.confファイルを変更する

[root@localhost redis-4.0.10]# vim redis.conf 
daemonize yes  #开启后台运行模式
protected-mode no  #开启远程访问权限
bind 0.0.0.0  #或者将这一行注释掉

⑥Redisを開始します

[root@localhost src]# ./redis-server ../redis.conf 
# 因为前面配置文件修改为后台运行模式,所以验证是否成功查看redis进行号
[root@localhost src]# ps aux | grep "redis"
root      1490  0.0  1.0 145312  7664 ?        Ssl  12:23   0:00 ./redis-server *:6379
root      1495  0.0  0.1 112724   996 pts/0    R+   12:23   0:00 grep --color=auto redis

✓クライアントを起動します。デフォルトのポートは6379です。redis.confファイルのポート番号を変更して、次のようなコマンドを起動することもできます:./ redis-cli -p 7000

[root@localhost src]# ./redis-cli

2.2 Redisクラスターバージョン(ローカルシミュレーション、3マスターモードと3スレーブモードを使用)

①ファイアウォールをオフにします

systemctl stop firewalld
systemctl disable firewalld

②redisクラスター環境をインストールする

yum install ruby
gem install redis-3.2.1.gem

③解凍

tar -zxf  redis-4.0.10.tar.gz

④コンパイル

[root@localhost redis-4.0.10]# make

⑤さまざまなポートをシミュレートするので、解凍ディレクトリにフォルダを作成してシミュレートし、各ファイルの下にredis.confファイルを作成しないようにし、構成ファイルを変更します。

cluster-enabled  yes 	        	//开启集群模式
cluster-config-file  nodes-7000.conf 		//集群节点配置文件
cluster-node-timeout  5000      	//集群节点超时时间
appendonly  yes 

⑥スタートノード7000〜7005

[root@localhost src]# ./redis-server ../7000/redis.conf

✓すべてのハッシュスロットをカバーする

./redis-trib.rb create --replicas 1 192.168.139.172:7000 192.168.139.172:7001 192.168.139.172:7002 192.168.139.172:7003 192.168.139.172:7004 192.168.139.172:7005

ここに画像の説明を挿入します
⑧クラスターノードのステータスを表示する

./redis-trib.rb check 192.168.139.172:7000

⑨クライアントを起動します

./redis-cli -c -p 7000

3.Redisの永続性メカニズム

Redisは、スナップショット(snapShotting)AOF追加ファイル(ファイルのみを追加という2つの異なる永続性メカニズムを提供します

3.1スナップショット(snapShotting)

このメソッドは、特定の時点ですべてのデータをハードディスクに書き込むことができます。もちろん、保存されたファイルは.rdb形式で終わるファイルであるため、これはredisのデフォルトの永続化メソッドでもあります。このメソッドはRDBメソッドとも呼ばれます。

redis.confで、.rdbのファイル名とファイル

の保存パスを確認できます。
ここに画像の説明を挿入します
スナップショットを作成するには2つの方法があります。BGSAVEセーブ
(A)SAVE
はSAVEコマンドを使用してスナップショットを作成できます。SAVEコマンドを受信したredisサーバーは、スナップショットが作成される前に他のコマンドに応答しなくなります。これをブロッキング状態と呼びます。redisは、shutdownコマンドを使用してサーバーをシャットダウンする要求を受信すると、saveコマンドを実行し、すべてのクライアントをブロックし、クライアントから送信されたコマンドを実行しなくなり、saveコマンドの実行後にサーバーをシャットダウンします。

(B)BGSAVE
はBGSAVEコマンドを使用してスナップショットを作成できます。クライアントからBGSAVEコマンドを受信すると、redisはforkを呼び出して子プロセスを作成し、子プロセスはスナップショットをディスクに書き込む役割を果たします。親プロセスは引き続きコマンド要求を処理します。

fork関数:親スレッドと子スレッドを作成します。クライアント呼び出しがある場合、親スレッドと子スレッドはそれぞれ独自のメモリを使用します。クライアントが呼び出さない場合、子スレッドは親スレッドのメモリ処理スナップショットを占有します。
ここに画像の説明を挿入します
スナップショットの実行サイクルはredis.confZで設定できます。図に示すデフォルトの構成は、1分間に10,000回、5分間に10回、または15分間に1回変更されることを意味します

スナップショット方式の欠点の分析:redisプロセスが直接強制終了されるなどの異常な終了の場合、スナップショットは時間がなくなる前にデータ損失を引き起こします。

3.2 AOF追加ファイル(ファイルのみ追加)

redisのデフォルト設定では、AOF永続性メカニズムはオンになっていません。AOF永続性は、redisがAOFを最初から1回実行する限り、実行された書き込みコマンドをAOFファイルの最後に書き込んでデータの変更を記録します。ファイルに含まれるすべての書き込みコマンドは、AOFファイルの記録されたデータセットを復元できます。

AOF永続化メカニズムをオンにします。redis.confで、appendonlyをyesに変更する
ここに画像の説明を挿入します
か、生成されたaofファイルの名前を
ここに画像の説明を挿入します
指定します。ログ更新の頻度を指定します。
ここに画像の説明を挿入します

オプション 同期周波数
常に 各redis書き込みコマンドは、ハードディスクに同期的に書き込む必要があります。これにより、redisの速度が大幅に低下します。
毎秒 1秒に1回同期を実行して、複数の書き込みコマンドをディスクに明示的に同期します
番号 オペレーティングシステムは、いつ同期するかを決定します

分析:使用する場合常にオプションを選択すると、すべてのredis書き込みコマンドがハードディスクに書き込まれ、システムのクラッシュ時に発生するデータ損失が最小限に抑えられます。残念ながら、この同期戦略ではハードディスク上で多数の書き込み操作が必要になるため、redisの処理速度コマンドの範囲は、ハードディスクのパフォーマンスによって制限されます。
注:ターンテーブルハードディスクは、この頻度で約200コマンド/秒です。ソリッドステートディスク(SSD)は数百万コマンド/秒です。
警告:SSDを使用するユーザーは、alwaysオプションの使用に注意する必要があります。このモードでは、少量の書き込みが継続的に行われます。データこの慣行は、深刻な書き込み増幅の問題を引き起こす可能性があり、ソリッドステートドライブの寿命を元の数年から数か月に短縮します

データセキュリティと書き込みパフォーマンスを考慮に入れるために、使用を検討することができます毎秒redisがAOFファイルを1秒に1回の頻度で同期できるようにするオプション。redisがAOFファイルを1秒に1回同期する場合、パフォーマンスは永続性機能を使用しない場合とほぼ同じです。AOFファイルを1秒に1回同期することにより、redisはシステムがクラッシュし、1秒以内に生成されたデータが最大で失われることも保証できます(この方法をお勧めします)。

最後に、noオプションを使用すると、オペレーティングシステムがAOFログファイルを同期するタイミングを決定します。このオプションはredisのパフォーマンスには影響しませんが、システムがクラッシュすると、無期限のデータが失われます。さらに、ユーザーのハードディスクが書き込み操作を処理するのに十分な速度ではない場合ハードディスクへの書き込みを待機しているデータでバッファがいっぱいになると、redisはブロックされた状態になり、redis処理コマンド要求の速度が遅くなります(推奨されません)

AOFファイルの書き換え

aofメソッドも別の問題を引き起こします。永続ファイルはどんどん大きくなります。たとえば、incr testコマンドを100回呼び出すと、100個のコマンドすべてをファイルに保存する必要があります。実際、そのうち99個は冗長です。データベースの状態を復元するには、設定されたテスト100をファイルに保存するだけで十分です。AOFの永続ファイルを圧縮するために、Redisは2つのAOF書き換えメカニズムを提供します。BGREWRITEAOF構成ファイルredis.confのAuto-aof-rewrite-percentage

(1)BGREWRITEAOFコマンドを実行します。このコマンドをクライアントで直接実行します。
(2)redis.confのauto-aof-rewrite-percentageの説明
ここに画像の説明を挿入します
:このアクションは自動的にBGREWRITEAOFを実行します。図に示すように、auto-aof-rewrite-percentageの値は100でauto-aof-rewrite-最小サイズ64mb、有効AOFが持続する場合、AOFファイルのボリュームが64Mを超え、AOFファイルのボリュームが最後の書き換え後のボリュームの少なくとも2倍(100%)大きい場合、自動的にトリガーされます。書き換えの頻度が高すぎる場合は、auto-aof-rewrite-percentageをより大きい値に設定することを検討できます。

AOF書き換えプロセス
①redisはforkを呼び出します。これで、fatherとsonの2つのプロセスがあり、子プロセスは、メモリ内のデータベーススナップショットに従って、データベースの状態を一時ファイルに再構築するコマンドを書き込みます。
②親プロセスは、元のaofファイルに書き込みコマンドを書き込むと同時に、受信した書き込みコマンドをバッファリングすることを除いて、クライアント要求を処理し続け、子プロセスが書き換えに失敗しても問題がないことを確認します。 。
③子プロセスがスナップショットの内容をコマンドで一時ファイルに書き込むと、子プロセスは親プロセスに信号を送信し、親プロセスもキャッシュされた書き込みコマンドを一時ファイルに書き込みます。
④これで、親プロセスは一時ファイルを使用して古いaofファイルを置き換え、名前を変更できます。また、後で受信した書き込みコマンドも新しいaofファイルへの追加を開始します。

4.Redis分散キャッシュ

既存のmybatisキャッシュのデメリット:
①Mybatisはローカルキャッシュに属し、プロジェクトがサーバーに配置されるとサーバーのメモリが占​​有されます。
②分散環境では、キャッシュ共有はできません。

mbatisは、追加、削除、変更を操作するときに自動的にキャッシュをクリアします。Redisは
分散キャッシュコードに使用され、Java言語は
ツールクラスを記述します。自分で実装したキャッシュのため、SpringBootは自分で実装したクラスをスキャンできず、自動インジェクションは使用できません。

package com.chinaTelecom.cache;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringContextUtil implements ApplicationContextAware {
    
    

   private static ApplicationContext context;
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
       context = applicationContext;
   }

   //获取整个工厂对象
   public static ApplicationContext getContext(){
    
    
       return context;
   }

   //根据名称获取指定bean
   public static Object getBean(String name){
    
    
       return context.getBean(name);
   }

   //根据类型获取指定bean
   public static Object getBean(Class clazz){
    
    
       return context.getBean(clazz);
   }

   //根据名称和类型获取
   public static Object getBean(String name,Class clazz){
    
    
       return context.getBean(name,clazz);
   }
}

関数実装コード

package com.chinaTelecom.cache;


import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class MybatisRedisCache implements Cache {
    
    

    private final String id; //id: 包名.DAO名,即mapper文件的namespace
    private final ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    public MybatisRedisCache(String id) {
    
    
        this.id = id;
    }

    @Override
    public String getId() {
    
    
        return null;
    }

    /**
     * @param key : 唯一值,代表方法唯一
     * @param value: 结果
     */
    @Override
    public void putObject(Object key, Object value) {
    
    
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtil.getBean("redisTemplate");
        redisTemplate.opsForHash().put(id,key,value);
    }

    @Override
    public Object getObject(Object key) {
    
    
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtil.getBean("redisTemplate");
        return redisTemplate.opsForHash().get(id,key);
    }

    @Override
    public Object removeObject(Object key) {
    
    
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtil.getBean("redisTemplate");
        return redisTemplate.opsForHash().delete(id,key);
    }

    @Override
    public void clear() {
    
    
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtil.getBean("redisTemplate");
        redisTemplate.opsForHash().delete(id);
    }

    @Override
    public int getSize() {
    
    
        RedisTemplate redisTemplate = (RedisTemplate)SpringContextUtil.getBean("redisTemplate");
        return redisTemplate.opsForHash().size(id).intValue();
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
    
    
        return reentrantReadWriteLock;
    }
}

おすすめ

転載: blog.csdn.net/qq_44962429/article/details/113754733