1. 程式人生 > >17-SpringBoot之Redis(四)——Redis流水線

17-SpringBoot之Redis(四)——Redis流水線

SpringBoot之Redis(四)——Redis流水線


在預設的情況下, Redis 客戶端是一條條命令傳送給Redis 伺服器的,這樣顯然效能不高。在關係資料庫中我們可以使用批量,也就是隻有需要執行SQL 時,才一次性地傳送所有的SQL 去執行,這樣效能就提高了許多。對於Redis 也是可以的,這便是流水線( pipline )技術,在很多情況下並不是Redis 效能不佳,而是網路傳輸的速度造成瓶頸,使用流水線後就可以大幅度地在需要執行很多命令時提升Redis 的效能。
為測試流水線效能,分別使用單條插入的方式和Redis流水線技術測試100 萬次讀寫的功能實驗,單條插入方式的實現程式碼如下:

@RequestMapping("/testSingle")
    public Map<String, Object> testSingle() {

        Long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++) {
            String key = "pipeline_" + i;
            String value = "value_" + i;
            redisTemplate.opsForValue().set
(key, value); } Long end = System.currentTimeMillis(); System.out.println("Single插入1000000條記錄耗時:" + (end - start) + "毫秒。"); Map<String, Object> map = new HashMap<String, Object>(); map.put("success", true); return map; }

使用redis流水線技術實現程式碼如下:

@RequestMapping("/testPipeline")
    public Map<String, Object> testPipeline() {

        Long start = System.currentTimeMillis();
        List List = redisTemplate.executePipelined(new RedisCallback<Long>() {
            @Nullable
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                connection.openPipeline();
                for (int i = 1000001; i < 2000000; i++) {
                    String key = "pipeline_" + i;
                    String value = "value_" + i;
                    connection.set(key.getBytes(), value.getBytes());
                }
                return null;
            }
        });

        Long end = System.currentTimeMillis();
        System.out.println("Pipeline插入1000000條記錄耗時:" + (end - start) + "毫秒。");

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("success", true);
        return map;
    }

分別呼叫這兩個方法。控制檯記錄的執行時間:

在這裡插入圖片描述

從實驗結果可以看出,使用redis流水線插入可以大幅度提高效能,它十分適合大資料量的執行。

這裡需要注意的是以下兩點。

  1. 在執行如此多的命令時,需要考慮的另外一個問題是記憶體空間的消耗,因為對於程式而言,它最終會返回一個List 物件,如果過多的命令執行返回的結果都儲存到這個List中,顯然會造成記憶體消耗過大,尤其在那些高併發的網站中就很容易造成JVM記憶體溢位的異常, 這個時候應該考慮使用迭代的方法執行Redis命令。
  2. 與事務一樣,使用流水線的過程中, 所有的命令也只是進入佇列而沒有執行,所以執行的命令返回值也為空,這也是需要注意的地方。