Redis-12Redis 流水线( pipeline )
生活随笔
收集整理的這篇文章主要介紹了
Redis-12Redis 流水线( pipeline )
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 概述
- JavaAPI 操作Redis Pipeline
- Spring操作Redis Pipeline
- 代碼
概述
Redis 的事務的各類問題,在事務中 Redis 提供了隊列, 這是一個可以批量執行任務的隊列,這樣性能就比較高,但是使用 multi…exec 事務命令是有系統開銷的,因為它會檢測對應的鎖和序列化命令。
有時候我們希望在沒有任何附加條件的場景下去使用隊列批量執行一系列的命令,從而提高系統性能,這就是 Redis 的流水線( pipelined )技術。
而現實中 Redis 執行讀/寫速度十分快,而系統的瓶頸往往是在網絡通信中的延時,如下
為了解決這個問題,可以使用 Redis 的流水線 , 但是 Redis 的流水線是一種通信協議沒有辦法通過客戶端演,不過我們可以通過 JavaAPI 或者使用 Spring 操作它.
前置條件: reids中的各種屬性JavaAPI或者是Spring操作的時候保持一致,一邊觀察性能。
JavaAPI 操作Redis Pipeline
package com.artisan.redis.pipelined;import java.util.List;import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Pipeline;public class PipelineWithJavaDemo {public static void main(String[] args) {// 實例化jedisPoolConfig并設置相關參數JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxIdle(6);jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxWaitMillis(3000);jedisPoolConfig.setMinEvictableIdleTimeMillis(300000);jedisPoolConfig.setTimeBetweenEvictionRunsMillis(30000);// 使用jedisPoolConfig初始化redis的連接池JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.31.66", 6379);// 從jedisPool中獲取一個連接Jedis jedis = jedisPool.getResource();jedis.auth("artisan");long beginTime = System.currentTimeMillis();// 開啟流水線Pipeline pipeline = jedis.pipelined();// 測試10 萬條的讀/寫 2 個操作for (int i = 0; i < 100000; i++) {int j = i + 1 ;jedis.set("pipeline_key" + j , "pipeline_value" + j);jedis.get("pipeline_key" + j);}// 這里只執行同步,但是不返回結果// pipeline.sync();// 將返回執行過的命令返回的 List 列表結果List list = pipeline.syncAndReturnAll();long endTime = System.currentTimeMillis();System.out.println("10 萬條的讀/寫 2 個操作 ,耗時:" + (endTime - beginTime) + "毫秒");}}輸出
10 萬條的讀/寫 2 個操作 ,耗時:87030毫秒Spring操作Redis Pipeline
在 Spring 中使用 RedisTemplate提供的 executePipelined 方法即可行流水線
package com.artisan.redis.pipelined;import java.util.List;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SessionCallback;public class PipelineWithSpringDemo {@SuppressWarnings({ "rawtypes", "unchecked", "unused", "resource" })public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring/spring-redis-string.xml");RedisTemplate redisTemplate = ctx.getBean(RedisTemplate.class);SessionCallback sessionCallback = (SessionCallback) (RedisOperations ops) -> {for (int i = 0; i < 100000; i++) {int j = i + 1 ;ops.boundValueOps("pipeline_key" + j).set("pipeline_value" + j);ops.boundValueOps("pipeline_key" + j).get();}return null;};long beginTime = System.currentTimeMillis();// 執行 Redis 的流水線命令List list = redisTemplate.executePipelined(sessionCallback);long endTime = System.currentTimeMillis();System.out.println("10 萬條的讀/寫 2 個操作 ,耗時:" + (endTime - beginTime));}} INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@73a8dfcc: startup date [Thu Sep 27 19:55:06 CST 2018]; root of context hierarchy INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [spring/spring-redis-string.xml] 10 萬條的讀/寫 2 個操作 ,耗時:2161這里只是為了測試性能而己,當你要執行很多的命令并返回結果的時候 , 需要考慮 List 對象的大小,因為它會“吃掉”服務器上許多的內存空間 , 嚴重時會導致內存不足,引發 JVM 溢出異常.
代碼
代碼托管到了 https://github.com/yangshangwei/redis_learn
總結
以上是生活随笔為你收集整理的Redis-12Redis 流水线( pipeline )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis-11使用 watch 命令监
- 下一篇: Redis-13Redis发布订阅