0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

对比两个基于Redis下的存储方案在性能方面的优劣

冬至配饺子 来源:开发内功修炼 作者:张彦飞allen 2022-08-30 17:13 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

现代的开发语言除了C++以外,大部分都对内存管理做好了封装,一般的开发者根本都接触不到内存的底层操作。更何况现在各种优秀的开源组件应用越来越多,例如mysql、redis等,这些甚至都不需要大家动手开发,直接拿来用就好了。所以有些同学也会觉得作为应用层开发的同学没有学习的必要去学习底层。

但我想通过本文的实际案例告诉大家,哪怕不直接接触内存底层操作,就只是用一些开源的工具,如果你能理解底层的工作原理,你也能够用到极致。

1 用于访问历史存储需求

假如现在有这样一个业务需求,用户每次刷新都需要获得要消费的新数据,但是不能和之前访问过的历史重复。你可以把它和你经常在用的今日头条之类的信息流app联系起来。每次都要看到新的新闻,但是你肯定不想看到过去已经看过的文章。这样在功能实现的时候,就必要保存用户的访问历史。当用户再来刷新的时候,首先得获取用户的历史记录,要保证推给用户的数据和之前的不重复。当推荐完成的时候,也需要把这次新推荐过的数据id记录到历史里。

为了适当降低实现复杂度,我们可以规定每个用户只要不和过去的一万条记录重复就可以了。这样每个用户最多只需要保存一万条历史id,如果存满了就把最早的历史记录挤掉。我们进一步具体化一下这个需求的几个关键点:

每个数据id是一个int整数来表示

每个用户要保存1万条id

每次用户刷新开始的时候需要将这1万条历史全部读取出来过滤一遍

每次用户刷新结束的时候需要将新访问过的10条写入一遍,如果超过1万需将最早的记录挤掉

可见,每次用户访问的时候,会涉及到一个1万规模的数据集上的一次读取和一次写入操作。好了,需求描述完了,我们怎么样进行我们的技术方案的设计呢?相信你也能想到很多实现方案,我们今天来对比两个基于Redis下的存储方案在性能方面的优劣。

2 Redis方案一:用list存储

首先能想到的第一个办法就是用Redis的List来保存。因为这个数据结构设计的太适合上面的场景了。List下的lrange命令可以实现一次性读取用户的所有数据id的需求。

$redis->lrange('TEST_KEY', 0,9999);

lpush命令可以实现新的数据id的写入,ltrim可以保证将用户的记录数量不超过1万条。

pYYBAGMN08uAUdOAAAAnX5dIbiQ827.png

我们准备一个用户,提前存好一万条id。写入的时候每次只写入10条新的id,读取的时候通过lrange一次全部读取出来。进行一下性能耗时测试,结果如下。

poYBAGMN09uAQwwVAAA8KE_cBD0711.png

3 Redis方案二:用string存储

我能想到的另外一个技术方案就是直接用String来存。我们可以把1万个int表示的数据id拼接成一个字符串,用一个特殊的字符把他们分割开。例如:"100000_100001_10002"这种。存储的时候,拼接一下,然后把这个大字符串写到Redis里。读取的时候,把大字符串整体读取出来,然后再用字符切割成数组来使用。

由于用string存储的时候,保存前多了一个拼接字符串的操作,读取后多了一步将字符串分割成数组的操作。在测试string方案的时候,为了公平起见,我们把需要把这两步的开销也考虑进来。核心代码如下:

poYBAGMN0_CAWg8LAABH9kH-xPI569.png

耗时测试结果如下

pYYBAGMN0_aACu3kAAAvCYE15Dw687.png

4 结论

我们再直观对比下两个技术方案的性能数据。

pYYBAGMN1AyAZMp0AAA3xaNNfdE101.png

基于list的方案里,写入速度非常快,只需要0.066ms,因为仅仅只需要写入新添加的10条记录就可以了,再加一次链表的截断操作,但是读取性能可就要慢很多了,超过了4ms。原因之一是因为读取需要整体遍历,但其实还有第二个原因。我们本案例中的数据量过大,所以Redis在内部实际上是用双端链表来实现的。

pYYBAGMN1B-ANd5bAABpFFSQs0I221.png

通过上图你可能看出来,链表是通过指针串起来的。大量的node之间极大可能是随机地分布在内存的各个位置上,这样你遍历整个链表的时候,实际上大概率会导致内存的随机模式下工作。

基于string方案在写入的时候耗时比list要高,因为每次都得需要将1万条全部写入一遍。但是读取性能却比list高了10倍,总体上耗时加起来大约只有方案一的1/4左右。为什么?我们再来看下redis string数据结构的内存布局

poYBAGMN1EGATahpAABZyrvxW70481.png

可见,如果用string来存储的话,不管用户的数据id有多少,访问将全部都是顺序IO。顺序IO的好处有两点:

1. 一内存的顺序IO的耗时大约只是随机IO的1/3-1/4左右,

2. 对于读取来说,顺序访问将极大地提升CPU的L1、L2、L3的cache命中率

所以如果你深入了内存的工作原理,哪怕你不能直接去操作内存,即使只是用一些开源的软件,你也能够将它的性能发挥到极致~



审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储器
    +关注

    关注

    39

    文章

    7716

    浏览量

    170961
  • 字符串
    +关注

    关注

    1

    文章

    594

    浏览量

    23070
  • Redis
    +关注

    关注

    0

    文章

    390

    浏览量

    12073
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【产品应用】储能网关EM-1000与EM-1000G的Redis性能对比

    视频推荐随着储能控制系统智能化发展,对实时处理和高速缓存需求提升。本测试对EM-1000与EM-1000G的Redis性能进行对比,评估其吞吐、响应与稳定性上的差异,为客户提供精准硬
    的头像 发表于 12-02 11:39 123次阅读
    【产品应用】储能网关EM-1000与EM-1000G的<b class='flag-5'>Redis</b><b class='flag-5'>性能对比</b>

    如何使用 SPI 全双工两个 5LP MPU 之间连接 RAM?

    并将其存储相同的内存位置中,从而将数据位置与数据进行镜像。 我想我 I2C 部分读过一允许这种类型传输的 API,但我不确定在哪里找到它。 我
    发表于 07-15 06:20

    Redis集群部署与性能优化实战

    Redis作为高性能的内存数据库,现代互联网架构中扮演着关键角色。作为运维工程师,掌握Redis的部署、配置和优化技能至关重要。本文将从实战角度出发,详细介绍
    的头像 发表于 07-08 17:56 671次阅读

    【经验分享】Omni3576上编译Redis-8.0.2源码,并安装及性能测试

    本文首先介绍Redis是什么,然后介绍如何在Omni3576上编译Redis-8.0.2源码,以及从源码编译、安装Redis,最后介绍如何在Omni3576上运行Redis
    的头像 发表于 06-05 08:05 783次阅读
    【经验分享】<b class='flag-5'>在</b>Omni3576上编译<b class='flag-5'>Redis</b>-8.0.2源码,并安装及<b class='flag-5'>性能</b>测试

    隔离变压器绕组用铜线和铝线的优劣对比

    电气工程的广阔天地中,隔离变压器虽不起眼,却扮演着举足轻重的角色,其性能和稳定性直接影响到整个系统的运行效果,因此,隔离变压器线圈材质的挑选显得尤为关键,目前,主要有种材质:铜线和铝线,那么面对这
    的头像 发表于 06-04 15:07 1072次阅读
    隔离变压器绕组用铜线和铝线的<b class='flag-5'>优劣</b><b class='flag-5'>对比</b>

    【幸狐Omni3576边缘计算套件试用体验】Redis最新8.0.2版本源码安装及性能测试

    的结果进行对比。 一、Redis是什么 维基百科的介绍是: Redis是一使用ANSI C编写的开源、支持网络、基于内存、分布式、可选持久性的键值对
    发表于 06-03 01:28

    redis三种集群方案详解

    Redis中提供的集群方案总共有三种(一般一redis节点不超过10G内存)。
    的头像 发表于 03-31 10:46 1303次阅读
    <b class='flag-5'>redis</b>三种集群<b class='flag-5'>方案</b>详解

    石墨膜和铜VC散热性能和应用方面的区别

    石墨散热膜与铜VC(均热板)散热性能和应用方面的区别如下:一、散热性能对比1.导热机制◎石墨散热膜:依赖石墨材料平面方向的高导热性(15
    的头像 发表于 03-13 17:13 2174次阅读
    石墨膜和铜VC散热<b class='flag-5'>性能</b>和应用<b class='flag-5'>方面的</b>区别

    DLP4710和DLP4710LC,两个套件中的DMD是不是一样的呢?

    ,DLPDLCR4710EVM-G2全高清 DLP4710 芯片组评估模块,我对比了一两个套件,发现它们用的方案基本是一样的,除了DLP驱动芯片,一
    发表于 02-19 07:13

    Redis实战笔记

    目前的技术选型中,Redis 俨然已经成为了系统高性能缓存方案的事实标准,因此现在 Redis 也成为了后端开发的基本技能树之一。   基
    的头像 发表于 02-09 09:12 650次阅读
    <b class='flag-5'>Redis</b>实战笔记

    FDD与传统通信技术的对比

    FDD(Frequency Division Duplex,频分双工)是一种双工通信技术,它与传统通信技术的对比主要体现在双工方式、频谱利用、系统复杂度、应用场景及性能特点等方面。以下是对这些
    的头像 发表于 01-07 16:43 1277次阅读

    华为云Flexus X实例,Redis性能加速评测及对比

    加速 Redis 的选项。本文旨在通过实际测试,展示华为云 Flexus X 实例加速 Redis 方面的性能优势,并与其他业界 U1 实
    的头像 发表于 12-29 15:47 862次阅读
    华为云Flexus X实例,<b class='flag-5'>Redis</b><b class='flag-5'>性能</b>加速评测及<b class='flag-5'>对比</b>

    EMMC与UFS的技术对比

    eMMC(Embedded Multi Media Card)与UFS(Universal Flash Storage)是种不同的存储技术,它们多个方面存在显著的技术差异。以下是对
    的头像 发表于 12-25 09:44 6746次阅读

    Redis使用重要的两个机制:Reids持久化和主从复制

    今天这篇文章,我们一起了解 Redis 使用中非常重要的两个机制:Reids 持久化和主从复制。 我们都知道Redis是一内存数据库,在学习主从同步之前,我们首先要想到
    的头像 发表于 12-18 10:33 641次阅读
    <b class='flag-5'>Redis</b>使用重要的<b class='flag-5'>两个</b>机制:Reids持久化和主从复制

    Redis缓存与Memcached的比较

    关键特性和差异: 1. 数据存储 Redis: Redis是一开源的键值存储,支持多种数据结构,如字符串、列表、集合、有序集合、散列、位图
    的头像 发表于 12-18 09:33 940次阅读