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;
}
}