Redisファジー操作の問題分析と解決策(redisTemplateに基づく)

需要の背景

		redis存在多个前缀相同的key,有时需要对其进行批量查询,删除,插入。当key大了,会坑惨CPU,因为redis通过tcp对外提供服务,是要i一个多路复用的单线程,每次请求的命令都是生成一个连接,所以后面的命令会阻塞直到前面的服务处理完毕才会继续。所以呢,存在一个隐患,这个隐患也只有量起来后才会出现,当我们循环获取key的时候,一开一合,耗时啊。

解決

バージョン2.8より上では、低すぎることは不可能のようです。

パイプラインを導入する時が来ました。パイプラインは、多数のコマンドを実行するときに多くのブロックによって引き起こされる遅延を解決するテクノロジーです。

実際、原則は非常に単純です。パイプラインは、頻繁な送受信によって引き起こされるネットワークオーバーヘッドを回避するために、すべてのコマンドを一度に送信することです。パッケージを再作成して一連のコマンドを受信した後、それらは順番に実行され、次にパッケージ化されます。結果はクライアントに返されます。

プロジェクト内のキャッシュデータ構造の実際の状況に応じて、データ構造はRedisTemplateのmultiGetメソッドを使用する文字列タイプです。データ構造はハッシュであり、パイプライン(パイプライン)を使用し、コマンドを組み合わせて、redisをバッチ処理します。

いわゆる非誘導操作。

シーン1

指定されたプレフィックスを持つキーの値をバッチ挿入/クエリします
multiGetを使用してバッチで取得します

フルバージョンの例

/**
 * 批量获取key的value
 *
 * @param keys
 * @return
 */
public List<Object> getMul(Collection<String> keys) {
    
    
    List<String> list= (List<String>) keys;
    //方法1
	redisTemplate.executePipelined(new SessionCallback<Object>() {
    
    
		@Override
		public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
    
    
			for (String s : list) {
    
    
				//查询
				redisTemplate.opsForValue().get(s);
				//插入
				redisTemplate.opsForValue().set(s, "testValue");
			}
			return null;
		}
	});

	//方法2
	redisTemplate.executePipelined(new RedisCallback<Object>() {
    
    
		@Override
		public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
    
    
			StringRedisConnection stringRedisConnection = (StringRedisConnection) redisConnection;
			for (String s : list) {
    
    
				//查询
				stringRedisConnection.get(s);
				//插入
				stringRedisConnection.set(s, "testValue");
			}
			return null;
		}
	});
	return redisTemplate.opsForValue().multiGet(keys);
}

シーン2

指定されたプレフィックスのキー値をバッチで削除するには
、1。keysメソッドを使用してあいまい一致を行い、deleteメソッドを呼び出してそれを取り除くことができますが、キーが大きすぎると、一致が遅すぎます、パフォーマンスに影響します。
2.このキャッシュを2段階で処理することを検討できます。
バッチで削除する必要があるため、挿入する必要があります。バッチで挿入する方法は、上記と同じです。ただし、挿入するときに、同じプレフィックスを持つこれらのキーをリストセットに入れるために、もう1つの手順を実行できます。コードは図に示すとおりです。
ここに写真の説明を挿入
これは明確なはずです。指定したプレフィックスを持つキーを削除しましょう。、次に最初にこのリストからすべてのキーを取り出してから、deleteメソッドを呼び出します。redisTemplateに付属のdeleteメソッドはバッチ削除をサポートしており、それらを書き換えるためにパイプラインを導入する必要はありません。
コードは次のように表示されます。
ここに写真の説明を挿入

これにより、すべてのあいまい一致が回避されます。もちろん、この種の書き込みでは、一貫性などの詳細を考慮する必要があります。

おすすめ

転載: blog.csdn.net/NICVSY/article/details/112984072