最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis大量數(shù)據(jù)插入過程

 更新時間:2025年08月05日 08:40:33   作者:懶蟲蟲~  
本文介紹Redis處理大數(shù)據(jù)插入的三種高效方法:redis-cli管道模式、Jedis pipelined()方法及RedisTemplate批量保存,旨在減少通信開銷并提升吞吐量

有些時候,Redis實例需要裝載大量用戶在短時間內(nèi)產(chǎn)生的數(shù)據(jù),數(shù)以百萬計的keys需要被快速的創(chuàng)建。

我們稱之為大量數(shù)據(jù)插入(mass insertion),本文檔的目標就是提供如下信息:Redis如何盡可能快的處理數(shù)據(jù)。

本文參考網(wǎng)上方案特意整理總結(jié)如下:

方式一:使用Luke協(xié)議,通過redis-cli –pipe發(fā)送數(shù)據(jù)到服務器

使用正常模式的Redis 客戶端執(zhí)行大量數(shù)據(jù)插入不是一個好主意:因為一個個的插入會有大量的時間浪費在每一個命令往返時間上。

使用管道(pipelining)是一種可行的辦法,但是在大量插入數(shù)據(jù)的同時又需要執(zhí)行其他新命令時,這時讀取數(shù)據(jù)的同時需要確保請可能快的的寫入數(shù)據(jù)。

只有一小部分的客戶端支持非阻塞輸入/輸出(non-blocking I/O),并且并不是所有客戶端能以最大限度的提高吞吐量的高效的方式來分析答復。

例如,如果我們需要生成一個10億的`keyN -> ValueN’的大數(shù)據(jù)集,我們會創(chuàng)建一個如下的redis命令集的文件:

SET Key0 Value0
SET Key1 Value1
...
SET KeyN ValueN

從Redis 2.6開始redis-cli支持一種新的被稱之為pipe mode的新模式用于執(zhí)行大量數(shù)據(jù)插入工作。使用pipe mode模式的執(zhí)行命令如下:

cat data.txt | redis-cli --pipe

這將產(chǎn)生類似如下的輸出:

All data transferred. Waiting for the last reply...
Last reply received from server.
errors: 0, replies: 1000000

使用redis-cli將有效的確保錯誤輸出到Redis實例的標準輸出里面。

1.1 生成Redis協(xié)議

它會非常簡單的生成和解析Redis協(xié)議,Redis協(xié)議文檔請參考Redis協(xié)議說明。 但是為了生成大量數(shù)據(jù)插入的目標,你需要了解每一個細節(jié)協(xié)議,每個命令會用如下方式表示:

*<args><cr><lf>
$<len><cr><lf>
<arg0><cr><lf>
<arg1><cr><lf>
...
<argN><cr><lf>

這里的是”\r”(或者是ASCII的13)、是”\n”(或者是ASCII的10)。

例如:命令SET key value協(xié)議格式如下:

*3<cr><lf>
$3<cr><lf>
SET<cr><lf>
$3<cr><lf>
key<cr><lf>
$5<cr><lf>
value<cr><lf>

或表示為引用字符串:

"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n"

你需要將大量插入數(shù)據(jù)的命令按照上面的方式一個接一個的生成到文件。

1.2 pipe mode的工作原理是什么?

dis-難點是保證recli在pipe mode模式下執(zhí)行和netcat一樣快的同時,如何能理解服務器發(fā)送的最后一個回復。

這是通過以下方式獲得:

redis-cli –pipe試著盡可能快的發(fā)送數(shù)據(jù)到服務器。

讀取數(shù)據(jù)的同時,解析它。

  • 一旦沒有更多的數(shù)據(jù)輸入,它就會發(fā)送一個特殊的ECHO命令,后面跟著20個隨機的字符。我們相信可以通過匹配回復相同的20個字符是同一個命令的行為。
  • 一旦這個特殊命令發(fā)出,收到的答復就開始匹配這20個字符,當匹配時,就可以成功退出了。

同時,在分析回復的時候,我們會采用計數(shù)器的方法計數(shù),以便在最后能夠告訴我們大量插入數(shù)據(jù)的數(shù)據(jù)量。

1.3 示例代碼操作

1.3.1 準備數(shù)據(jù)文件,格式是文本文件,名稱是:redis_commands.txt。

我在Windows環(huán)境下生成了一個txt文件,一條數(shù)據(jù)一行,代碼如下:

                 SET Key0 Value0
                 SET Key1 Value1
                 SET Key2 Value2
                 SET Key3 Value3
                 SET Key4 Value4
                 SET Key5 Value5
                 SET Key6 Value6
                 SET Key7 Value7
                 SET Key8 Value8
                 SET Key9 Value9
                 SET Key10 Value10
                 ...
                 SET KeyN ValueN
public class getStringTest {
    /**
     * 格式化成輸入字符串
     */
    private String getString(String... args) {
        StringBuilder sb = new StringBuilder();
        sb.append("*").append(args.length).append("\r\n");
        for (String arg : args) {
            sb.append("$").append(arg.length()).append("\r\n");
            sb.append(arg).append("\r\n");
        }
        return sb.toString();
    }
 
    @Test
    public void initFile2() {
        Long startTime = System.currentTimeMillis();
        String file = "d:\\d.txt";
        BufferedWriter w = null;
        StringBuilder sb = new StringBuilder();
        try {
            w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
                for(int i=0 ;i < 10000000;i++){
                //for (int i = 1; i <= 100; i++) {
                if (i / 3 == 0) {
                    w.flush();
                }
                sb.setLength(0);
                sb.append(this.getString("set", "u" + i, "name" + i));
//sb.append(this.getString("hmset", "usr" + i, "userid", "usr" + i, "username", "usrname" + i));
                w.append(sb.toString());
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                w.flush();
                w.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("耗時: "+(endTime - startTime)/1000+" s。");
    }
}

我生成了1000萬的數(shù)據(jù),因為這個文本文件我是在Windows環(huán)境下生成的,所以需要格式轉(zhuǎn)換。

1.3.2 如果使用Windows環(huán)境下生成的文件,需要進行格式轉(zhuǎn)換,如果是在Linux環(huán)境下生成的文件就不需要格式轉(zhuǎn)換,如果文本文件比較大,執(zhí)行轉(zhuǎn)換時間會有幾秒,等待即可。

執(zhí)行格式轉(zhuǎn)換

[root@linux ~]# unix2dos redis_commands.txt
unix2dos:converting file redis_commands.txt to DOS format ...

以上代碼進行格式轉(zhuǎn)換完畢

需要說明一點,unix2dos這個命令需要先安裝,如果沒有安裝,會提示:command not found。

執(zhí)行以下命令安裝:

[root@linux ~]# yum install unix2dos

1.3.3 進行數(shù)據(jù)批量插入

[root@linux ~]# cat d.txt | redis-cli -h 134.177.11.22 -p 6379 [-a "password"] -n 0 --pipe
All data transferred.Waiting for the last reply...
Last reply received from server.
errors:0,replies:10000000

方案二:采用Jedis的父類中的pipelined()方法獲取管道

我們可以采用Jedis的父類中的pipelined()方法獲取管道,它可以實現(xiàn)一次性發(fā)送多條命令并一次性返回結(jié)果,這樣就大量的減少了客戶端與Redis的通信次數(shù),可以有效的提高程序效率(但是,因為Redis要一次性返回所有結(jié)果,它會把這些結(jié)果都緩存起來,因此命令越多,緩存消耗的內(nèi)存也會越大,具體還要視情況而定).此外Pipeline的原理是隊列(先進先出),這樣也保證了數(shù)據(jù)的順序性。

public static void main(String[] args) throws Exception {
 
        Jedis jedis = new Jedis("127.0.0.1", 6474);
        Pipeline p = jedis.pipelined();
        p.setex("key_a", 120, "11111");
        p.setex("key_b", 120, "2222");
        p.sync();
        if (jedis != null && jedis.isConnected()) {
            jedis.close();
        }
    }

方案三:使用RedisTemplate批量保存數(shù)據(jù)

public void saveDataToRedis(Map<String, String> map) {
        redisTemplate.executePipelined(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                map.forEach((key, value) -> connection.set(redisTemplate.getKeySerializer().serialize(key), redisTemplate.getValueSerializer().serialize(value)));
                return null;
            }
        });
    }

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • Redis Sorted Set類型使用及應用場景

    Redis Sorted Set類型使用及應用場景

    Sorted Set是Redis常用的一種是數(shù)據(jù)類型,本文主要介紹了Redis Sorted Set類型使用及應用場景,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • 使用Redis有序集合實現(xiàn)IP歸屬地查詢詳解

    使用Redis有序集合實現(xiàn)IP歸屬地查詢詳解

    這篇文章主要介紹了使用Redis有序集合實現(xiàn)IP歸屬地查詢,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Redis高效查詢大數(shù)據(jù)的實踐與優(yōu)化詳細指南

    Redis高效查詢大數(shù)據(jù)的實踐與優(yōu)化詳細指南

    Redis 是一種高性能的鍵值存儲數(shù)據(jù)庫,廣泛應用于緩存,排行榜,計數(shù)器等場景,本文將圍繞如何高效查詢Redis中滿足條件的數(shù)據(jù)展開討論,感興趣的小伙伴可以了解下
    2025-04-04
  • 使用rpm包安裝redis的方法

    使用rpm包安裝redis的方法

    Redis是一款高性能的Key-Value數(shù)據(jù)庫,其開源免費且具有高可用性等,本文主要介紹了使用rpm包安裝redis的方法,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Redis正確使用的十個技巧

    Redis正確使用的十個技巧

    Redis已經(jīng)走過了很長的一段路,隨之而來的一系列最佳實踐,使得大多數(shù)人可以正確地使用Redis,下面我們將探索正確使用 Redis 的10個技巧。
    2015-10-10
  • Redis中五種數(shù)據(jù)類型簡單操作

    Redis中五種數(shù)據(jù)類型簡單操作

    這篇文章主要介紹了Redis中五種數(shù)據(jù)類型簡單操作的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Redis存儲的列表分頁和檢索的實現(xiàn)方法

    Redis存儲的列表分頁和檢索的實現(xiàn)方法

    在 Redis 中,列表(List)是一種有序的數(shù)據(jù)結(jié)構(gòu),通常用于存儲一系列元素,由于列表是有序的,可以通過索引來訪問元素,因此可以很方便地實現(xiàn)分頁和檢索功能,以下是 Redis 列表的分頁和檢索的實現(xiàn)方法,需要的朋友可以參考下
    2025-02-02
  • Redis動態(tài)字符串SDS的實現(xiàn)

    Redis動態(tài)字符串SDS的實現(xiàn)

    SDS在Redis中是實現(xiàn)字符串對象的工具,本文主要介紹了Redis動態(tài)字符串SDS的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • 使用redis-cli命令實現(xiàn)redis crud操作過程

    使用redis-cli命令實現(xiàn)redis crud操作過程

    線上Redis key需刪除但無法直連客戶端,可用redis-cli命令操作,步驟包括定位服務、登錄、選擇數(shù)據(jù)庫及執(zhí)行DEL命令,適用于無圖形工具的環(huán)境
    2025-08-08
  • redis-copy使用6379端口無法連接到Redis服務器的問題

    redis-copy使用6379端口無法連接到Redis服務器的問題

    這篇文章主要介紹了redis-copy使用6379端口無法連接到Redis服務器的問題的相關(guān)資料,需要的朋友可以參考下
    2023-05-05

最新評論

崇信县| 成武县| 桂阳县| 美姑县| 都匀市| 福贡县| 白河县| 汕尾市| 内江市| 温宿县| 武宣县| 金乡县| 连云港市| 美姑县| 婺源县| 安溪县| 阜平县| 贡觉县| 大洼县| 唐河县| 阳高县| 云梦县| 新建县| 德阳市| 贵州省| 青神县| 金堂县| 象州县| 新宁县| 鹰潭市| 邹平县| 镇江市| 文水县| 崇左市| 松阳县| 交城县| 永州市| 噶尔县| 界首市| 磐石市| 内黄县|