返回顶部
首页 > 资讯 > 精选 >Redis命令使用实例分析
  • 449
分享到

Redis命令使用实例分析

2023-06-27 10:06:09 449人浏览 八月长安
摘要

这篇文章主要讲解了“Redis命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis命令使用实例分析”吧!问题原因小编负责的应用是一个管理后台应用,权限管理使用 shiro

这篇文章主要讲解了“Redis命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis命令使用实例分析”吧!

问题原因

小编负责的应用是一个管理后台应用,权限管理使用 shiro 框架,由于存在多个节点,需要使用分布式 Session,于是这里使用 Redis 存储 Session 信息。

由于 Shiro 并没有直接提供 Redis 存储 Session 组件,阿粉不得不使用 GitHub 一个开源组件 shiro-redis。

由于 Shiro 框架需要定期验证 Session 是否有效,于是 Shiro 底层将会调用  SessionDAO#getActiveSessions 获取所有的 Session 信息。

shiro-redis 正好继承 SessionDAO 这个接口,底层使用用keys 命令查找 Redis 所有存储的 Session key。

public Set<byte[]> keys(byte[] pattern){    checkAndInit();    Set<byte[]> keys = null;    Jedis jedis = jedisPool.getResource();    try{        keys = jedis.keys(pattern);    }finally{        jedis.close();    }    return keys;}

找到问题原因,解决办法就比较简单了,github 上查找到解决方案,升级一下 shiro-redis 到最新版本。

在这个版本,shiro-redis 采用 scan命令代替 keys,从而修复这个问题。

public Set<byte[]> keys(byte[] pattern) {    Set<byte[]> keys = null;    Jedis jedis = jedisPool.getResource();    try{        keys = new HashSet<byte[]>();        ScanParams params = new ScanParams();        params.count(count);        params.match(pattern);        byte[] cursor = ScanParams.SCAN_POINTER_START_BINARY;        ScanResult<byte[]> scanResult;        do{            scanResult = jedis.scan(cursor,params);            keys.addAll(scanResult.getResult());            cursor = scanResult.getCursorAsBytes();        }while(scanResult.getStrinGCursor().compareTo(ScanParams.SCAN_POINTER_START) > 0);    }finally{        jedis.close();    }    return keys;}

虽然问题成功解决了,但是阿粉心里还是有点不解。

为什么keys 指令会导致其他命令执行变慢?

为什么Keys 指令查询会这么慢?

为什么Scan 指令就没有问题?

Redis 执行命令的原理

首先我们来看第一个问题,为什么keys 指令会导致其他命令执行变慢?

站在客户端的视角,执行一条命令分为三步:

  1. 发送命令

  2. 执行命令

  3. 返回结果

但是这仅仅客户端自己以为的过程,但是实际上同一时刻,可能存在很多客户端发送命令给 Redis ,而 Redis 我们都知道它采用的是单线程模型。

为了处理同一时刻所有的客户端的请求命令,Redis 内部采用了队列的方式,排队执行。

于是客户端执行一条命令实际需要四步:

  1. 发送命令

  2. 命令排队

  3. 执行命令

  4. 返回结果

由于 Redis 单线程执行命令,只能顺序从队列取出任务开始执行。

只要 3 这个过程执行命令速度过慢,队列其他任务不得不进行等待,这对外部客户端看来,Redis 好像就被阻塞一样,一直得不到响应。

所以使用 Redis 过程切勿执行需要长时间运行的指令,这样可能导致 Redis 阻塞,影响执行其他指令。

KEYS 原理

接下来开始回答第二个问题,为什么Keys 指令查询会这么慢?

回答这个问题之前,请大家回想一下 Redis 底层存储结构。

不太清楚朋友的也没关系,大家可以回看一下之前的文章「阿里面试官:HashMap 熟悉吧?好的,那就来聊聊 Redis 字典吧!」。

keys命令需要返回所有的符合给定模式 pattern 的  Redis 中键,为了实现这个目的,Redis 不得不遍历字典中 ht[0]哈希表底层数组,这个时间复杂度为 「O(N)」(N 为 Redis 中 key 所有的数量)。

如果 Redis 中 key 的数量很少,那么这个执行速度还是也会很快。等到 Redis key 的数量慢慢更加,上升到百万、千万、甚至上亿级别,那这个执行速度就会很慢很慢。

下面是阿粉本地做的一次实验,使用 lua 脚本往 Redis 中增加 10W 个 key,然后使用 keys 查询所有键,这个查询大概会阻塞十几秒的时间。

eval "for i=1,100000  do redis.call('set',i,i+1) end" 0

这里阿粉使用 Docker 部署 Redis,性能可能会稍差。

SCAN 原理

最后我们来看下第三个问题,为什么scan 指令就没有问题?

这是因为 scan命令采用一种黑科技-「基于游标的迭代器」

每次调用 scan 命令,Redis 都会向用户返回一个新的游标以及一定数量的 key。下次再想继续获取剩余的 key,需要将这个游标传入 scan 命令, 以此来延续之前的迭代过程。

简单来讲,scan 命令使用分页查询 redis 。

下面是一个 scan 命令的迭代过程示例:

scan 命令使用游标这种方式,巧妙将一次全量查询拆分成多次,降低查询复杂度。

虽然  scan 命令时间复杂度与 keys一样,都是 「O(N)」,但是由于 scan 命令只需要返回少量的 key,所以执行速度会很快。

最后,虽然scan 命令解决 keys不足,但是同时也引入其他一些缺陷:

  • 同一个元素可能会被返回多次,这就需要我们应用程序增加处理重复元素功能。

  • 如果一个元素在迭代过程增加到 redis,或者说在迭代过程被删除,那个这个元素会被返回,也可能不会。

以上这些缺陷,在我们开发中需要考虑这种情况。

除了 scan以外,redis 还有其他几个用于增量迭代命令:

  • sscan:用于迭代当前数据库中的数据库键,用于解决 smembers可能产生阻塞问题

  • hscan命令用于迭代哈希键中的键值对,用于解决 hgetall 可能产生阻塞问题。

  • zscan:命令用于迭代有序集合中的元素(包括元素成员和元素分值),用于产生 zrange 可能产生阻塞问题。

感谢各位的阅读,以上就是“Redis命令使用实例分析”的内容了,经过本文的学习后,相信大家对Redis命令使用实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: Redis命令使用实例分析

本文链接: https://lsjlt.com/news/309772.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Redis命令使用实例分析
    这篇文章主要讲解了“Redis命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis命令使用实例分析”吧!问题原因小编负责的应用是一个管理后台应用,权限管理使用 Shiro...
    99+
    2023-06-27
  • fold命令使用实例分析
    本篇内容介绍了“fold命令使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!fold命令用于限制文件列宽,其会从指定的文件里读取内...
    99+
    2023-06-27
  • file命令使用实例分析
    今天小编给大家分享一下file命令使用实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。file命令用来探测给定文件的类...
    99+
    2023-06-27
  • sed命令使用实例分析
    这篇文章主要介绍“sed命令使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“sed命令使用实例分析”文章能帮助大家解决问题。sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件...
    99+
    2023-06-27
  • type命令使用实例分析
    这篇文章主要介绍“type命令使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“type命令使用实例分析”文章能帮助大家解决问题。type命令 用来显示指定命令的类型,判断给出的指令是内部指...
    99+
    2023-06-27
  • Linux gpasswd命令使用实例分析
    这篇文章主要讲解了“Linux gpasswd命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux gpasswd命令使用实例分析”吧!Linux常用命令gpasswd命...
    99+
    2023-06-28
  • Linux comm命令使用实例分析
    这篇文章主要讲解了“Linux comm命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux comm命令使用实例分析”吧!如何使用 comm比较两个排序好的文件要使用c...
    99+
    2023-06-27
  • linux中mkdir命令使用实例分析
    这篇文章主要介绍“linux中mkdir命令使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux中mkdir命令使用实例分析”文章能帮助大家解决问题...
    99+
    2024-04-02
  • linux中pwd命令使用实例分析
    这篇文章主要介绍“linux中pwd命令使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“linux中pwd命令使用实例分析”文章能帮助大家解决问题。lin...
    99+
    2024-04-02
  • linux中ls命令使用实例分析
    本篇内容介绍了“linux中ls命令使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ls命令是l...
    99+
    2024-04-02
  • linux中rmdir命令使用实例分析
    本篇内容介绍了“linux中rmdir命令使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!rmd...
    99+
    2024-04-02
  • Linux的trap命令使用实例分析
    本篇内容介绍了“Linux的trap命令使用实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!通过使用tr,您可以非常容易地实现 sed...
    99+
    2023-06-27
  • Linux的chattr命令使用实例分析
    这篇文章主要讲解了“Linux的chattr命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux的chattr命令使用实例分析”吧!chattr 命令用于设置文件的隐藏权...
    99+
    2023-06-27
  • Linux的mv命令实例使用分析
    今天小编给大家分享一下Linux的mv命令实例使用分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。mv命令用来对文件或目录...
    99+
    2023-06-28
  • Linux的cm命令实例使用分析
    本文小编为大家详细介绍“Linux的cm命令实例使用分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Linux的cm命令实例使用分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。命令名称:cd代表:切换目录使...
    99+
    2023-06-27
  • Linux的mread命令使用实例分析
    今天小编给大家分享一下Linux的mread命令使用实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Linux mre...
    99+
    2023-06-27
  • Linux的ip命令使用实例分析
    这篇文章主要介绍“Linux的ip命令使用实例分析”,在日常操作中,相信很多人在Linux的ip命令使用实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux的ip命令使用实例分析”的疑惑有所帮助!...
    99+
    2023-06-27
  • Linux的od命令使用实例分析
    这篇文章主要讲解了“Linux的od命令使用实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux的od命令使用实例分析”吧!Linux常用命令od命令 用于输出文件的八进制、十六...
    99+
    2023-06-28
  • Linux中的命令使用实例分析
    这篇文章跟大家分析一下“Linux中的命令使用实例分析”。内容详细易懂,对“Linux中的命令使用实例分析”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“Linux中的命令使用实例...
    99+
    2023-06-28
  • Linux的ipcalc命令使用实例分析
    这篇文章主要介绍“Linux的ipcalc命令使用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Linux的ipcalc命令使用实例分析”文章能帮助大家解决问题。Linux常用命令ipcal...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作