码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 单线程Jedis管道实现批量写入数据


    前言

            生产中的有些场景,我们经常需要大批量的往Redis中写入数据,如果我们采用单条循环写入的话,不仅效率低下,而且可能会出现频繁的创建和销毁redis连接,这些都是很不合理的.

            对此,我们可以采用Jedis的父类中的pipelined()方法获取管道,它可以实现一次性发送多条命令并一次性返回结果,这样就大量的减少了客户端与Redis的通信次数,可以有效的提高程序效率(但是,因为Redis要一次性返回所有结果,它会把这些结果都缓存起来,因此命令越多,缓存消耗的内存也会越大,具体还要视情况而定).此外Pipeline的原理是队列(先进先出),这样也保证了数据的顺序性.

    代码实现

    maven依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-data-redisartifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>redis.clientsgroupId>
    7. <artifactId>jedisartifactId>
    8. dependency>
    9. <dependency>
    10. <groupId>org.springframework.bootgroupId>
    11. <artifactId>spring-boot-configuration-processorartifactId>
    12. <optional>trueoptional>
    13. dependency>

    配置文件配置redis

    1. redis.dateBase=1
    2. redis.url=192.168.3.111
    3. redis.password=123456
    4. redis.port=6379
    5. redis.maxTotal=200
    6. redis.maxWait=5000
    7. redis.maxIdle=5
    8. redis.minIdle=0
    9. redis.timeout=0

    读取配置文件内容并自动封装成实体类

    将redis的host,port,database封装到实体中。

    1. import lombok.Data;
    2. import org.springframework.boot.context.properties.ConfigurationProperties;
    3. import org.springframework.stereotype.Component;
    4. @ConfigurationProperties(prefix = "redis")
    5. @Component
    6. @Data
    7. public class RedisConfigProperties {
    8. private Integer dateBase;
    9. private String url;
    10. private String password;
    11. private Integer port;
    12. }

    Pipeline实现批量插入示例

    实现逻辑如下:

    1. 首先创建一个新的Jedis连接;
    2. 输入密码后指定database;
    3. 根据Jedis创建一个新的Pipeline;
    4. 调用hset方法批量写入;
    5. 批量写入完成后调用syncAndReturnAll方法统一写入redis;
    6. 最后关闭Jedis连接。
    1. @Component
    2. @Order(value = 2)
    3. public class MeteValueApplicationRunner implements ApplicationRunner {
    4. @Autowired
    5. RedisConfigProperties redisConfigProperties;
    6. @Override
    7. public void run(ApplicationArguments args) {
    8. Jedis jedis = new Jedis(redisConfigProperties.getUrl(), redisConfigProperties.getPort());
    9. // 输入密码
    10. jedis.auth(redisConfigProperties.getPassword());
    11. // 指定redis的database
    12. jedis.select(redisConfigProperties.getDateBase());
    13. Pipeline pipeline = jedis.pipelined();
    14. for (int i = 0; i < 10000; i++) {
    15. pipeline.hset("real_time_" + i, System.currentTimeMillis(), i);
    16. }
    17. List list = pipeline.syncAndReturnAll();
    18. jedis.disconnect();
    19. }
    20. }

    21. Pipeline批量设置过期时间

      使用pipeline的pexpire方法实现redis的key过期时间,源码如下:

      1. public Response pexpire(String key, long milliseconds) {
      2. this.getClient(key).pexpire(key, milliseconds);
      3. return this.getResponse(BuilderFactory.LONG);
      4. }

      可以看到传入参数为redis的key以及long类型的过期时间,过期时间可以通过org.springframework.data.redis.core.TimeoutUtils工具类中的toMillis方法得到,toMillis的源码如下:

      1. public static long toMillis(long timeout, TimeUnit unit) {
      2. return roundUpIfNecessary(timeout, unit.toMillis(timeout));
      3. }

      TimeUnit是JDK封装好的java.util.concurrent包下面的一个类,表示给定单元粒度的时间段。TimeUnit的所有颗粒度如下

      1. TimeUnit.DAYS //天
      2. TimeUnit.HOURS //小时
      3. TimeUnit.MINUTES //分钟
      4. TimeUnit.SECONDS //秒
      5. TimeUnit.MILLISECONDS //毫秒
      6. TimeUnit.MICROSSECONDS //微秒
      7. TimeUnit.NANOSSECONDS //纳秒

      示例:设置redis的过期为30天,代码如下:

      1. Integer timeout = 30;
      2. final TimeUnit unit = TimeUnit.DAYS;
      3. final long rawTimeout = TimeoutUtils.toMillis(timeout, unit);
      4. // 设置过期时间
      5. pipeline.pexpire("key", rawTimeout);

      上述通过Pipeline批量写入redis的代码改造如下:

      1. @Component
      2. @Order(value = 2)
      3. public class MeteValueApplicationRunner implements ApplicationRunner {
      4. @Autowired
      5. RedisConfigProperties redisConfigProperties;
      6. @Override
      7. public void run(ApplicationArguments args) {
      8. // 得到过期时间
      9. Integer timeout = 30;
      10. final TimeUnit unit = TimeUnit.DAYS;
      11. final long rawTimeout = TimeoutUtils.toMillis(timeout, unit);
      12. Jedis jedis = new Jedis(redisConfigProperties.getUrl(), redisConfigProperties.getPort());
      13. // 输入密码
      14. jedis.auth(redisConfigProperties.getPassword());
      15. // 指定redis的database
      16. jedis.select(redisConfigProperties.getDateBase());
      17. Pipeline pipeline = jedis.pipelined();
      18. for (int i = 0; i < 10000; i++) {
      19. pipeline.hset("real_time_" + i, System.currentTimeMillis(), i);
      20. pipeline.pexpire("real_time_" + i, rawTimeout);
      21. }
      22. List list = pipeline.syncAndReturnAll();
      23. jedis.disconnect();
      24. }
      25. }

      26. 相关阅读:
        HTTPS建立连接的过程
        〖Python 数据库开发实战 - MySQL篇㉕〗- 数据更新操作 - UPDATE 语句
        接口自动化测试实操
        聊聊 C# 和 C++ 中的 泛型模板 底层玩法
        LeetCode 1879. 两个数组最小的异或值之和【记忆化搜索,状压DP,位运算】2145
        运维 Windows cmd 操作
        【JavaScript】string类型字符串常见算法题
        弘辽科技:淘宝店铺被管控还能开吗?原因是什么?
        甘露糖-聚乙二醇-CY5 Cy5-PEG-mannose
        游戏主机配置
      27. 原文地址:https://blog.csdn.net/qq_37634156/article/details/127571181
        • 最新文章
        • 攻防演习之三天拿下官网站群
          数据安全治理学习——前期安全规划和安全管理体系建设
          企业安全 | 企业内一次钓鱼演练准备过程
          内网渗透测试 | Kerberos协议及其部分攻击手法
          0day的产生 | 不懂代码的"代码审计"
          安装scrcpy-client模块av模块异常,环境问题解决方案
          leetcode hot100【LeetCode 279. 完全平方数】java实现
          OpenWrt下安装Mosquitto
          AnatoMask论文汇总
          【AI日记】24.11.01 LangChain、openai api和github copilot
        • 热门文章
        • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
          奉劝各位学弟学妹们,该打造你的技术影响力了!
          五年了,我在 CSDN 的两个一百万。
          Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
          面试官都震惊,你这网络基础可以啊!
          你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
          心情不好的时候,用 Python 画棵樱花树送给自己吧
          通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
          13 万字 C 语言从入门到精通保姆级教程2021 年版
          10行代码集2000张美女图,Python爬虫120例,再上征途
        Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
        正则表达式工具 cron表达式工具 密码生成工具

        京公网安备 11010502049817号