SpringBoot整合Redis管道的示例代碼
1. Redis 之管道(pipeline)
執(zhí)行一個Redis命令,Redis客戶端和Redis服務器就需要執(zhí)行以下步驟:
- 客戶端發(fā)送命令到服務器;
- 服務器接受命令請求,執(zhí)行命令,產(chǎn)生相應的結果;
- 服務器返回結果給客戶端;
- 客戶端接受命令的執(zhí)行結果,并向用戶展示。
Redis命令所消耗的大部分時間都用在了發(fā)送命令請求和接收命令結果上面,把任意多條Redis命令請求打包在一起,然后一次性地將它們全部發(fā)送給服務器,而服務器則會把所有命令請求都處理完畢之后,一次性地將它們的執(zhí)行結果全部返回給客戶端。
注意事項:
Redis服務器并不會限制客戶端在管道中包含的命令數(shù)量,但是卻會為客戶端的輸入緩沖區(qū)設置默認值為1GB的體積上限:當客戶端發(fā)送的數(shù)據(jù)量超過這一限制時,Redis服務器將強制關閉該客戶端。因此最好不要一下把大量命令或者一些體積非常龐大的命令放到同一個管道中執(zhí)行。
除此之外,很多客戶端本身也帶有隱含的緩沖區(qū)大小限制,如果你在使用流水線特性的過程中,發(fā)現(xiàn)某些流水線命令沒有被執(zhí)行,或者流水線返回的結果不完整,那么很可能就是你的程序觸碰到了客戶端內置的緩沖區(qū)大小限制。
2. SpringBoot 整合 Redis 管道實例
使用單個的 increment 命令,處理 200w個key:
public class RedisPipelineStudy extends BaseTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final String PREFIX = "test0:";
@Test
public void test() {
StopWatch stopWatch = new StopWatch();
stopWatch.start("test0");
for (int times = 0; times < 2; times++) {
for (int i = 0; i < 1000000; i++) {
stringRedisTemplate.opsForValue().increment(PREFIX + i, 1L);
}
}
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
}
耗時如下所示:是 12 位 ,單位ns

使用管道 incrBy 處理 200w個key,每次打包300條命令發(fā)送給服務器,如下所示:
public class RedisPipelineStudy extends BaseTest {
@Autowired
private StringRedisTemplate stringRedisTemplate;
private static final String PREFIX = "test1:";
@Test
public void test() {
StopWatch stopWatch = new StopWatch();
stopWatch.start("test1");
List<Integer> recordList = new ArrayList<>();
for (int times = 0; times < 2; times++) {
for (int i = 0; i < 1000000; i++) {
try {
recordList.add(i);
if (recordList.size() > 300) {
incrByPipeline(recordList);
recordList = new ArrayList<>();
}
} catch (Exception e) {
System.out.println(e);
}
}
if (!CollectionUtils.isEmpty(recordList)) {
incrByPipeline(recordList);
recordList = new ArrayList<>();
}
}
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
private void incrByPipeline(List<Integer> recordList) {
stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
try {
for (Integer record : recordList) {
byte[] key = (PREFIX + record).getBytes();
connection.incrBy(key, 1);
}
} catch (Exception e) {
System.out.println(e);
}
return null;
}
});
}
}
耗用時間: 11 位 ,單位 :ns,是單個命令耗時的 1/6。

到此這篇關于SpringBoot整合Redis管道的示例代碼的文章就介紹到這了,更多相關SpringBoot整合Redis管道內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring中ImportBeanDefinitionRegistrar源碼和使用方式
Spring容器擴展流程總結:1. 定義Mapper層,2. 通過FactoryBean創(chuàng)建代理對象,3. 使用ImportBeanDefinitionRegistrar修改Bean定義,4. 應用自定義注解@LuoyanImportBeanDefinitionRegistrar,5. 配置類中執(zhí)行后置處理器,6. 啟動類中查看源碼,希望對大家有所幫助2024-11-11

