当前位置:

首页 > 编程开发 > redis中多样的数据类型及集群相关的知识有哪些

redis中多样的数据类型及集群相关的知识有哪些

Redis Assistant
Redis Assistant

Redis Assistant 是一款为Redis设计的高效可视化管理与监控工具,提供多种操作模式,高效处理服务器数据。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。

立即下载
¥19
Windows/macOS/Linux 2026-08-22
正版软件 Windows macOS软件 Linux 数据库管理工具

多样的数据类型string类型简单方便,支持空间预分配,也就是每次会多分配点空间,这样string如果下次变长的话,就不需要额外的申请空了,当然前提是剩余的空间够用。【相关推荐:Redis视频教程】List类型可以实现简单的消息队列,但是注意可能存在消息丢失哦,它并不持ACK模式。Hash表有点像关系型数据库,但是当hash表越来越大的时候,请注意,避免使用hgetall之类的语句,因为请求大量的数据会导致redis阻塞,这样后面的兄弟们就得等待了。set集合类型可以帮你做一些统计,比如你要统计某天活跃的

本文目录

    redis中多样的数据类型及集群相关的知识有哪些

    多样的数据类型

    string 类型简单方便,支持空间预分配,也就是每次会多分配点空间,这样 string 如果下次变长的话,就不需要额外的申请空了,当然前提是剩余的空间够用。【相关推荐:Redis视频教程】

    List 类型可以实现简单的消息队列,但是注意可能存在消息丢失哦,它并不持 ACK 模式。

    Hash 表有点像关系型数据库,但是当 hash 表越来越大的时候,请注意,避免使用 hgetall 之类的语句,因为请求大量的数据会导致redis阻塞,这样后面的兄弟们就得等待了。

    set 集合类型可以帮你做一些统计,比如你要统计某天活跃的用户,可以直接把用户ID扔到集合里,集合支持一些骚操作,比如 sdiff 可以获取集合之间的差集,sunion 可以获取集合之间的并集,功能很多,但是一定需要谨慎,因为牛逼的功能是有代价的,这些操作需要耗费一些 CPU 和IO 资源,可能会导致阻塞,因此大集合之间的骚操作要慎用,

    zset 可以说是最闪耀的星,可以做排序,因为可以排序,因此应用场景挺多,比如点赞前xx名用户,延时队列等等。

    bitmap 位图的好处就是在于节省空间,特别在做一些统计类的方面,比如要统计某一天有多少个用户签到了并且某个用户是否签到了,如果不用bitmap的话,你可能会想到用set。

    SADD day 1234//签到就添加到集合
    SISMEMBER day 1234//判断1234是否签到
    SCARD day   //有多少个签到的

    set 在功能上可以满足,但是相比bitmap的话,set要更耗费存储空间,set的底层主要是由整数集合或者 hashtable 组成,整数集合只有在数据量非常小的情况下才会使用,一般是小于512个元素,同时元素必须都是整数,对于set来说,整数集合的数据更加紧凑,他们在内存是上连续的,查询的话只能是二分查找了,时间复杂度是O(logN),而 hashtable 就不同了,这里的 hashtable 和 redis 的5大数据类型中的hash是一样的,只不过没有 value 而已,value 指向个 null,同时也不存在冲突,因为这里是集合,但是需要考虑 rehash 相关问题。ok,扯的有点远,我们说的用户签到问题,在用户非常多的情况下,set 的话肯定会用到 hashtable,hashtable 的话,其实每个元素都是个 dictEntry 结构体

    typedef struct dictEntry {
        // 键
        void *key;
        // 值
        union {
            void *val;
            uint64_t u64;
            int64_t s64;
        } v;
        // 指向下个哈希表节点,形成链表
        struct dictEntry *next;
    
    } dictEntry;

    从这个结构体可以看到什么呢?首先虽然值 union(没有 value)和 next(没有冲突)是空的,但是结构体本身需要空间,还需要加上个 key,这个占用空间是实打实的,而如果用 bitmap 的话,一个bit位就可以代表一个数字,很省空间,我们来看看 bitmap 的方式如何设置和统计。

    SETBIT day 1234 1//签到
    GETBIT day 1234//判断1234是否签到
    BITCOUNT day//有多少个签到的

    bf 这是 redis4.0 之后支持的布隆过滤器 RedisBloom,但是需要单独加载对应的 module,当然我们也可以基于上述的 bitmap 来实现自己的布隆过滤器,不过既然 redis 已经支持了,通过 RedisBloom 可以减少我们的开发时间,布隆过滤器是干嘛的,我这里就不赘述了,直接来看看 RedisBloom 相关的用法吧。

    # 可以通过docker的方式快速拉取镜像来玩耍
    docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
    docker exec -it redis-redisbloom bash
    redis-cli
    # 相关操作
    bf.reserve sign 0.001 10000
    bf.add sign 99 //99这个用户加入
    bf.add exists 99//判断99这个用户是否存在

    因为布隆过滤器是存在误判的,所有 bf 支持自定义误判率,0.001就代表误判率,10000 代表布隆过滤器可以存储的元素个数,当实际存储的元素个数超过这个值的时候,误判率会提高。

    HyperLogLog 可以用于统计,它的优点就是占用的存储空间极小,只需要 12KB 的内存就可以统计 2^64 个元素,那它主要统计什么呢?其实主要就是基数统计,比如像 UV 这种,从功能上来说 UV 可以用 set 或者 hash 来存储,但是缺点就是耗费存储,容易使之变成大 key,如果想要节省空间,bitmap 也可以,12KB 空间的 bitmap 只能统计 12*1024*8=98304个元素,而 HyperLogLog 却可以统计 2^64 个元素,但是这么牛逼的技术其实是有误差的,HyperLogLog 是基于概率来统计的,标准误算率是 0.81%,在统计海量数据并且对精度要求不那么高的场景下,HyperLogLog 在节省空间这块还是很优秀的。

    PFADD uv 1 2 3 //1 2 3是活跃用户
    PFCOUNT uv //统计

    GEO 是可以应用在地理位置的业务上,比如微信附近的人或者附近的车辆等等,先来看一下如果没有GEO 这种数据结构,你如何知道你附近的人?首先得上报自己的地理位置信息吧,比如经度 116.397128,纬度 39.916527,此时可以用 string、hash 数据类型存储,但是如果要查找你附近的人,string 和 hash 这种就无能为例了,你不可能每次都要遍历全部的数据来判断,这样太耗时了,当然你也不可能通过 zset 这种数据结构来把经纬度信息当成权重,但是如果我们能把经纬度信息通过某种方式转换成一个数字,然后当成权重好像也可以,这时我们只需通过zrangebyscore key v1 v2也可以找到附近的人。真的需要这么麻烦吗?于是 GEO 出现了,GEO 转换经纬度为数字的方法是“二分区间,区间编码”,这是什么意思呢?以经度为例,它的范围是[-180,180],如果要采用3位编码值,那么就是需要二分3次,二分后落在左边的用0表示,右边的用1表示,以经度是121.48941 来说,第一次是在[0,180]这个区间,因此记1,第二次是在[90,180],因此再记1,第三次是在[90,135],因此记0。纬度也是同样的逻辑,假设此时对应的纬度编码后是010,最后把经纬度合并在一起,需要注意的是经度的每个值在偶数位,纬度的每个值在奇数位。

    1 1 0   //经度
     0 1 0  //纬度
    ------------
    101100 //经纬度对应的数值

    原理是这样,我们再来看看 redis 如何使用 GEO:

    GEOADD location 112.123456 41.112345 99 //上报用户99的地理位置信息
    GEORADIUS location  112.123456 41.112345 1 km ASC COUNT 10 //获取附近1KM的人

    搞懂集群

    生产环境用单实例 redis 的应该比较少,单实例的风险在于:

    • 单点故障即服务故障,没有backup

    • 单实例压力大,又要提供读,又要提供写

    于是我们首先想到的就是经典的主从模式,而且往往是一主多从,这是因为大部分应用都是读多写少的情况,我们的主负责更新,从负责提供读,就算我们的主宕机了,我们也可以选择一个从来充当主,这样整个应用依然可以提供服务。

    复制过程的细节

    当一个 redis 实例首次成为某个主的从的时候,这时主得把数据发给它,也就是 rdb 文件,这个过程 master 是要 fork 一个子进程来处理的,这个子进程会执行 bgsave 把当前的数据重新保存一下,然后准备发给新来的从,bgsave 的本质是读取当前内存中的数据然后保存到 rdb 文件中,这个过程涉及大量的 IO,如果直接在主进程中来处理的话,大概率会阻塞正常的请求,因此使用个子进程是个明智的选择。

    那 fork 的子进程在 bgsave 过程中如果有新的变更请求会怎么办?

    严格来说子进程出来的一瞬间,要保存的数据应该就是当时那个点的快照数据,所以是直接把当时的内存再复制一份吗?不复制的话,如果这期间又有变更改怎么办?其实这要说到写实复制(COW)机制,首先从表象上来看内存是一整块空间,其实这不太好维护,因此操作系统会把内存分成一小块一小块的,也就是内存分页管理,一页的大小一般是4K、8K或者16K等等,redis 的数据都是分布在这些页面上的,出于效率问题,fork 出来的子进程是和主进程是共享同一块的内存的,并不会复制内存,如果这期间主进程有数据变更,那么为了区分,这时最快捷的做法就是把对应的数据页重新复制一下,然后主的变更就在这个新的数据页上修改,并不会修改来的数据页,这样就保证了子进程处理的还是当时的快照。

    以上说的变更是从快照的角度来考虑的,如果从数据的一致性来说,当快照的 rdb 被从库应用之后,这期间的变更该如何同步给从库?答案是缓冲区,这个缓冲区叫做 replication buffer,主库在收到需要同步的命令之后,会把期间的变更都先保存在这个缓冲区中,这样在把 rdb 发给从库之后,紧接着会再把 replication buffer 的数据也发给从库,最终主从就保持了一致。

    replication buffer不是万能的补给剂

    我们来看看 replication buffer 持续写入的时间有多长。

    • 我们知道主从同步的时候,主库会执行 fork 来让子进程完成相应地工作,因此子进程从开始执行 bgsave 到执行完毕这期间,变更是要写入 replication buffer 的。

    • rdb 生成好之后,需要把它发送给从库,这个网络传输是不是也需要耗点时间,这期间也是要写入 replication buffer 的。

    • 从库在收到 rdb 之后需要把 rdb 应用到内存里,这期间从库是阻塞的,无法提供服务,因此这期间也是要写入 replication buffer 的。

    replication buffer 既然是个 buffer,那么它的大小就是有限的,如果说上面3个步骤中,只要有一个耗时长,就会导致 replication buffer 快速增长(前提是有正常的写入),当 replication buffer 超过了限制之后就会导致主库和从库之间的连接断开,断开之后如果从库再次连接上来就会导致重新开始复制,然后重复同样的漫长的复制步骤,因此这个 replication buffer 的大小还是很关键的,一般需要根据写入的速度、每秒写入的量和网络传输的速度等因素来综合判断。

    从库网络不好和主库断了该怎么办?

    正常来说,只要主从之间的连接建立好了,后面主库的变更可以直接发给从库,让从库直接回放,但是我们并不能保证网络环境是百分百的通畅的,因此也要考虑从库和主库之间的断联问题。

    应该是在 redis2.8 以前,只要从库断联,哪怕只有很短的时间,后面从库再次连接上来的时候,主库也会直接无脑的进行全量同步。在 2.8 版本及以后,开始支持增量复制了,增量复制的原理就是得有个缓冲区来保存变更的记录,这里这个缓冲区叫做repl_backlog_buffer,这个缓冲区从逻辑上来说是个环形缓冲区,写满了就会从头开始覆盖,所以也有大小限制。在从库重新连接上来的时候,从库会告诉主库:“我当前已经复制到了xx位置”,主库收到从库的消息之后开始查看xx位置的数据是否还在 repl_backlog_buffer 中,如果在的话,直接把xx后面的数据发给从库即可,如果不在的话,那无能为力了,只能再次进行全量同步。

    需要一个管理者

    在主从模式下,如果主库挂了,我们可以把一个从库升级成主库,但是这个过程是手动的,靠人力来操作,不能使损失降到最低,还是需要一套自动管理和选举的机制,这就是哨兵,哨兵它本身也是个服务,只不过它不处理数据的读写而已,它只负责管理所有的 redis 实例,哨兵每隔一段时间会和各个 redis 通信(ping 操作),每个 redis 实例只要在规定的时间内及时回复,就可以表明自己的立场。当然哨兵本身也可能存在宕机或者网络不通的情况,因此一般哨兵也会搭建个哨兵集群,这个集群的个数最好是奇数,比如3个或者5这个这种,奇数的目的主要就是为了选举(少数服从多数)。

    当某个哨兵在发起 ping 后没有及时收到 pong,那么就会把这个 redis 实例标记下线,此时它还是不是真正的下线,这时其他的哨兵也会判定当前这个哨兵是不是真正的下线,当大多数哨兵都认定这个 redis 是下线状态,那么就会把它从集群中踢出去,如果下线的是从库,那么还好,直接踢出去就ok,如果是主库还要触发选举,选举也不是盲目选举,肯定是要选出最合适的那个从来充当新的主库。这个最合适充当主库的库,一般会按照以下优先级来确定:

    • 权重,每个从库其实都可以设置一个权重,权重越高的从库会被优先选择

    • 复制的进度,每个从库复制的进度可能是不一样的,优先选择当前和主库数据差距最小的那个

    • 服务的 ID,其实每个 redis 实例都有自己的 ID,如果以上条件都一样,那么会选择 ID 最小的那个库来充当主库

    更强的横向伸缩性

    主从模式解决了单点故障问题,同时读写分离技术使得应用支撑能力更强,哨兵模式可以自动监管集群,实现自动选主,自动剔除故障节点的能力。

    正常来说只要读的压力越来越大,我们可以添加从库来缓解,那如果主库压力很大怎么办?这就得提到接下来要说的分片技术了,我们只需要把主库切成几片,部署到不同的机器上即可。这个分片就是 redis 中的槽概念了,当分片的时候,redis 会默认分成 0~16383 也就是一共 16384 个槽,然后把这些槽平均分到每个分片节点上就可以起到负载均衡的作用了。每个 key 具体该分到哪个槽中,主要是先 CRC16 得到一个 16bit 的数字,然后这个数字再对 16384 取模即可:

    crc16(key)%16384

    然后客户端会缓存槽信息,这样每当一个 key 到来时,只要通过计算就知道该发给哪个实例来处理来了。但是客户端缓存的槽信息并不是一成不变的,比如在增加实例的时候,这时候会导致重新分片,那么原来客户端缓存的信息就会不准确,一般这时候会发生两个常见的错误,严格来说也不是错误,更像一种信息,一个叫做MOVED,一个叫做ASK。moved的意思就说,原来是实例A负责的数据,现在被迁移到了实例B,MOVED 代表的是迁移完成的,但是 ASK 代表的是正在迁移过程中,比如原来是实例A负责的部分数据,现在被迁移到了实例B,剩下的还在等待迁移中,当数据迁移完毕之后 ASK 就会变成 MOVED,然后客户端收到 MOVED 信息之后就会再次更新下本地缓存,这样下次就不会出现这两个错误了。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    php72w redis,docker php7安装php-redis
    php72w redis,docker php7安装php-redis

    在Docker环境下为PHP安装Redis扩展:手动编译需下载源码、安装phpize、配置编译并安装,生成redis.so并在php.d目录新建redis.ini加载,重启PHP-FPM;也可直接yum安装php72w-pecl-redis,免手动编译。

    php 如何配置 redis,php 如何设置redis
    php 如何配置 redis,php 如何设置redis

    配置PHP的Redis扩展:先安装Redis服务,从GitHub下载phpredis源码,用phpize编译安装,修改php.ini添加extension=redis.so,重启php-fpm或Apache,通过phpinfo验证并连接Redis。

    c++如何将结构体序列化为Redis兼容的RESP协议格式【深度】
    c++如何将结构体序列化为Redis兼容的RESP协议格式【深度】

    C++结构体无法直接序列化为RESP协议,需手动将字段映射为*N数组嵌套$lenbulkstring形式。整数需转换为字符串并加:前缀,空字符串用$0\r\n,null用$-1\r\n。长度计算需精确到字节数,特别注意二进制安全,同时确保字段顺序与结构体定义一致。

    如何在Golang架构中部署Redict作为高能数据临时存储中转站
    如何在Golang架构中部署Redict作为高能数据临时存储中转站

    Redis作为跨服务临时状态枢纽,需按消息队列、缓存和原子状态三重角色设计。选型用List实现任务分发及延迟重试,Stream用于事件广播与位点回溯。go-redis/v8需配置MinIdleConns、MaxRetries及超时。数据写入应JSON序列化并带type标签、设合理TTL、将关键字段提至顶层。消费通过原子GET+DEL或processedkey

    TP8.0 高并发下库存超卖?Redis 原子递减结合数据库乐观锁控制
    TP8.0 高并发下库存超卖?Redis 原子递减结合数据库乐观锁控制

    在高并发秒杀场景下,利用Redis的减库存原子操作预扣减库存拦截超卖请求,再通过数据库乐观锁(版本号与库存校验)确保最终一致性,异常时回滚Redis库存并借助Lua脚本保证原子性,从而有效防止库存超卖。

    如何在 Go 中利用 go-redis 执行 Lua 脚本优化逻辑
    如何在 Go 中利用 go-redis 执行 Lua 脚本优化逻辑

    在Go中使用go-redis执行Lua脚本可借助原子性解决竞态问题,通过redis.Script封装脚本并自动处理SHA1缓存与重试。需注意KEYS必须为非空切片且所有键在Cluster模式下落在同一slot,ARGV以字符串传入并由tonumber转换。返回值需先检查错误再调用Val(),避免panic。

    TP6.0 基于 Redis SetNX 实现的简单互斥锁机制【并发】
    TP6.0 基于 Redis SetNX 实现的简单互斥锁机制【并发】

    先看一个典型场景:电商秒杀、库存扣减、定时任务重复调度——这些并发冲突在 TP6 应用里屡见不鲜。用 Redis 的 SETNX 做互斥锁,确实是轻量又直接的方案,但“能用”和“稳妥”之间,隔着三层硬功夫:原子加锁、身份校验、合理超时。这三条,差一条就翻车。 很多人第一次上手,直接写 SETNX 加

    TP6.0 如何处理高并发抢购?Redis 原子锁与队列削峰详解【秒杀】
    TP6.0 如何处理高并发抢购?Redis 原子锁与队列削峰详解【秒杀】

    高并发抢购中,Redis的DECR原子操作可安全扣库存;配合think-queue异步削峰,接口仅扣库存和推消息;分布式锁需用SETNXEX加唯一标识,释放时用Lua脚本校验;成功资格后须以数据库事务双写为准,失败时补回Redis库存。

    Golang 实现基于 Redis 的延时任务队列
    Golang 实现基于 Redis 的延时任务队列

    基于Redis的ZSET实现延时队列需解决并发重复消费、失败重试混乱、精度不足及内存爆炸等问题。通过Lua脚本保证取删原子性,使用毫秒级时间戳,对临时错误采用指数退避重试,永久错误记入独立哈希表,并限制最大延迟、定期清理过期任务、使用紧凑序列化格式。

    RedisInsight怎么修改Key的过期时间 Redis操作方法【步骤】
    RedisInsight怎么修改Key的过期时间 Redis操作方法【步骤】

    操作 Redis 的时候,改个 Key 的过期时间其实是个高频场景。特别是做运维排查或者临时调试那会儿,谁也不想反复切命令行窗口、背那些命令参数。好在 RedisInsight 这个图形工具把这事儿做得很顺手——三种方式任选,总有一种合你胃口。 在动手前,先确认一下 Key 当前的 TTL 状态是个

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    即将离开本站
    您即将前往第三方网站,请确认是否继续?