redis的pipeline

uj3353 8年前發布 | 29K 次閱讀 Redis NoSQL數據庫

來自: https://segmentfault.com/a/1190000004448722

本文主要展示怎么在SpringDataRedis中使用pipeline。

pipeline概要

正常情況下,每個請求命令發出后client通常會阻塞并等待redis服務端處理,redis服務端處理完后將結果返回給client。當client使用pipeline發送命令時,redis server必須部分請求放到隊列中(使用內存)執行完畢后一次性發送結果。在一定程度上,可以較大的提升性能,性能提升的原因主要是TCP鏈接中較少了“交互往返”的時間。

使用

@Test
    public void pipeline(){
        List<Object> results = template.executePipelined(new RedisCallback<Object>() {
                    public Object doInRedis(RedisConnection connection) throws DataAccessException {
                        StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
                        for(int i=0; i< 10; i++) {
                            stringRedisConn.lPush("myqueue","item"+i);
                        }
                        return null;
                    }
                });
        results.stream().forEach(System.out::println);
    }

輸出

查看redis

127.0.0.1:6379> lrange myqueue 0 -1
 1) "item9"
 2) "item8"
 3) "item7"
 4) "item6"
 5) "item5"
 6) "item4"
 7) "item3"
 8) "item2"
 9) "item1"
10) "item0"

如果不需要返回結果,則可以使用redisTemplate的execute,然后傳入true給pipeline參數。

executePipelined源碼

public List<Object> executePipelined(final RedisCallback<?> action, final RedisSerializer<?> resultSerializer) {
        return execute(new RedisCallback<List<Object>>() {
            public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
                boolean pipelinedClosed = false;
                try {
                    Object result = action.doInRedis(connection);
                    if (result != null) {
                        throw new InvalidDataAccessApiUsageException(
                                "Callback cannot return a non-null value as it gets overwritten by the pipeline");
                    }
                    List<Object> closePipeline = connection.closePipeline();
                    pipelinedClosed = true;
                    return deserializeMixedResults(closePipeline, resultSerializer, resultSerializer, resultSerializer);
                } finally {
                    if (!pipelinedClosed) {
                        connection.closePipeline();
                    }
                }
            }
        });
    }

redis自帶的benchmark

redis自帶了redis-benchmark,可以用來測試redis的性能。不給定任何參數的情況下默認使用50個客戶端來進行性能測試。redis-benchmark不會處理執行命令所獲得的命令回復,所以它節約了大量用于對命令回復進行語法分析的時間。

redis-benchmark -c 1 -q
PING_INLINE: 58823.53 requests per second
PING_BULK: 60642.81 requests per second
SET: 59772.86 requests per second
GET: 60096.15 requests per second
INCR: 60532.69 requests per second
LPUSH: 60204.70 requests per second
LPOP: 58309.04 requests per second
SADD: 60350.03 requests per second
SPOP: 59066.75 requests per second
LPUSH (needed to benchmark LRANGE): 60313.63 requests per second
LRANGE_100 (first 100 elements): 37341.30 requests per second
LRANGE_300 (first 300 elements): 17934.00 requests per second
LRANGE_500 (first 450 elements): 13208.29 requests per second
LRANGE_600 (first 600 elements): 10604.45 requests per second
MSET (10 keys): 54171.18 requests per second

參考

 本文由用戶 uj3353 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!