华为架构师整理Redis数据结构的大厂最佳实践(上)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 华为架构师整理Redis数据结构的大厂最佳实践

1 概述

数据结构和内部编码

image.png

无传统关系型数据库的 Table 模型

schema 所对应的db仅以编号区分。同一 db 内,key 作为顶层模型,它的值是扁平化的。即 db 就是key的命名空间。

key的定义通常以:分隔,如:Article:Count:1

常用的Redis数据类型有:string、list、set、map、sorted-set

1.png

redisObject通用结构

Redis中的所有value 都是以object 的形式存在的,其通用结构如下

image.png

  • type 数据类型
    指 string、list 等类型
  • encoding 编码方式
    指的是这些结构化类型具体的实现方式,同一个类型可以有多种实现。e.g. string 可以用int 来实现,也可以使用char[] 来实现;list 可以用ziplist 或者链表来实现
  • lru
    本对象的空转时长,用于有限内存下长时间不访问的对象清理
  • refcount
    对象引用计数,用于GC
  • ptr 数据指针
    指向以 encoding 方式实现这个对象实际实现者的地址。如:string 对象对应的SDS地址(string的数据结构/简单动态字符串)

单线程

image.png

单线程为何这么快?

  • 纯内存
  • 非阻塞I/O
  • 避免线程切换和竞态消耗

image.png

  • 一次只运行一条命令
  • 拒绝长(慢)命令
    keys, flushall, flushdb, slow lua script, mutil/exec, operate big value(collection)
  • 其实不是单线程
    fysnc file descriptor
    close file descriptor

2 string

Redis中的 string 可表示很多语义

  • 字节串(bits)
  • 整数
  • 浮点数


redis会根据具体的场景完成自动转换,并根据需要选取底层的实现方式。

例如整数可以由32-bit/64-bit、有符号/无符号承载,以适应不同场景对值域的要求。


  • 字符串键值结构,也能是 JSON 串或 XML 结构

image.png

内存结构

在Redis内部,string的内部以 int、SDS(简单动态字符串 simple dynamic string)作为存储结构


  • int 用来存放整型
  • SDS 用来存放字节/字符和浮点型SDS结构


SDS

typedef struct sdshdr {
    // buf中已经占用的字符长度
    unsigned int len;
    // buf中剩余可用的字符长度
    unsigned int free;
    // 数据空间
    char buf[];
}

image.png

  • 结构图
    存储的内容为“Redis”,Redis采用类似C语言的存储方法,使用’\0’结尾(仅是定界符)。
    SDS的free 空间大小为0,当free > 0时,buf中的free 区域的引入提升了SDS对字符串的处理性能,可以减少处理过程中的内存申请和释放次数。

buf 的扩容与缩容

  • 当对SDS 进行操作时,如果超出了容量。SDS会对其进行扩容,触发条件如下:
  • 字节串初始化时,buf的大小 = len + 1,即加上定界符’\0’刚好用完所有空间
  • 当对串的操作后小于1M时,扩容后的buf 大小 = 业务串预期长度 * 2 + 1,也就是扩大2倍。
  • 对于大小 > 1M的长串,buf总是留出 1M的 free空间,即2倍扩容,但是free最大为 1M。

字节串与字符串

SDS中存储的内容可以是ASCII 字符串,也可以是字节串。由于SDS通过len 字段来确定业务串的长度,因此业务串可以存储非文本内容。对于字符串的场景,buf[len] 作为业务串结尾的’\0’ 又可以复用C的已有字符串函数。

SDS编码的优化

value 在内存中有2个部分:redisObject和ptr指向的字节串部分。

在创建时,通常要分别为2个部分申请内存,但是对于小字节串,可以一次性申请。


incr userid:pageview (单线程:无竞争)。缓存视频的基本信息(数据源在MySQL)

image.png

public VideoInfo get(Long id) {
  String redisKey = redisPrefix + id;
  VideoInfo videoInfo e redis.get(redisKey);
  if (videoInfo == null) {
    videoInfo = mysql.get(id);
    if (videoInfo != null) {
      // 序列化
      redis.set(redisKey serialize(videoInfo)):
    }
  }
}     

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

除此之外,string 类型的value还有一些CAS的原子操作,如:get、set、set value nx(如果不存在就设置)、set value xx(如果存在就设置)。


String 类型是二进制安全的,也就是说在Redis中String类型可以包含各种数据,比如一张JPEG图片或者是一个序列化的Ruby对象。一个String类型的值最大长度可以是512M。


在Redis中String有很多有趣的用法

  • 把String当做原子计数器,这可以使用INCR家族中的命令来实现:INCR, DECR, INCRBY。
  • 使用APPEND命令来给一个String追加内容。
  • 把String当做一个随机访问的向量(Vector),这可以使用GETRANGE和 SETRANGE命令来实现
  • 使用GETBIT 和SETBIT方法,在一个很小的空间中编码大量的数据,或者创建一个基于Redis的Bloom Filter 算法。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
9天前
|
XML JSON NoSQL
Redis的常用数据结构之字符串类型
Redis的常用数据结构之字符串类型
19 0
|
16天前
|
存储 消息中间件 NoSQL
Redis数据类型详解:选择合适的数据结构优化你的应用
Redis数据类型详解:选择合适的数据结构优化你的应用
|
21天前
|
存储 NoSQL 算法
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)(二)
【Redis技术进阶之路】「底层源码解析」揭秘高效存储模型与数据结构底层实现(字典)
34 0
|
5天前
|
监控 负载均衡 API
构建高性能微服务架构:后端开发的最佳实践
【4月更文挑战第14天】 在当今快速发展的软件开发领域,微服务架构已成为构建可扩展、灵活且容错的系统的首选方法。本文深入探讨了后端开发人员在设计和维护高性能微服务时需要遵循的一系列最佳实践。我们将从服务划分原则、容器化部署、API网关使用、负载均衡、服务监控与故障恢复等方面展开讨论,并结合实际案例分析如何优化微服务性能及可靠性。通过本文的阅读,读者将获得实施高效微服务架构的实用知识与策略。
|
21天前
|
存储 NoSQL Redis
作者推荐 |【Redis技术进阶之路】「原理系列开篇」揭秘高效存储模型与数据结构底层实现(SDS)(三)
作者推荐 |【Redis技术进阶之路】「原理系列开篇」揭秘高效存储模型与数据结构底层实现(SDS)
19 0
|
23天前
|
存储 NoSQL Java
Redis 数据结构操作入门
Redis 数据结构操作入门
15 0
|
9天前
|
NoSQL Linux Redis
06- 你们使用Redis是单点还是集群 ? 哪种集群 ?
**Redis配置:** 使用哨兵集群,结构为1主2从,加上3个哨兵节点,总计分布在3台Linux服务器上,提供高可用性。
18 0
|
17天前
|
负载均衡 监控 NoSQL
Redis的集群方案有哪些?
Redis集群包括主从复制(基础,手动故障恢复)、哨兵模式(自动高可用)和Redis Cluster(官方分布式解决方案,自动分片和容错)。此外,还有如Codis、Redisson和Twemproxy等第三方工具用于代理和负载均衡。选择方案需考虑应用场景、数据规模和并发需求。
17 2
|
23天前
|
NoSQL Redis
Redis集群(六):集群常用命令及说明
Redis集群(六):集群常用命令及说明
15 0
|
2月前
|
运维 NoSQL 算法
Redis-Cluster 与 Redis 集群的技术大比拼
Redis-Cluster 与 Redis 集群的技术大比拼
46 0