大数据基础--redis

Updated on in 程序人生 with 0 views and 0 comments

一、简介

  • redis是一个基于网络的、高性能的key-value内存数据库
  • redis跟memcached类似,不过数据可以持久化,支持的数据类型丰富
  • redis有以下几个特点
    • 高性能
    • 低时延
    • 丰富数据结构存取
    • 支持持久化

二、应用场景

  • 取最新N个数据的操作,例如博客网站获取最近的文章
  • 排行榜取TOP N,上面得需求以时间为权重,这里取TOP N以条件为权重
  • 设置精确过期时间得应用,如用户会话信息
  • 计数器应用,比如记录用户访问网站次数
  • 缓存,如缓存系统中经常访问的数据
  • 发布/订阅功能
  • 手机验证码,使用expire设置过期时间

二、业务流程

2.1 redis架构

  • 无中心自组织的架构,节点之间使用Gossip协议来交换节点状态信息
  • 各节点维护key->server得映射关系
  • Client节点可以向任意节点发起请求,节点不会转发请求,只是重定向client
  • 如果client在第一次请求和重定向之间,cluster拓扑发生变化,则第二次重定向将被再次重定向,直到找到正确的server

如下图所示,在第一次请求时,如果请求的数据不在节点中,redis会要求客户端重定向到正确节点,如果在请求和重定向之间,cluster拓扑发生了变化就会在重复做一次重定向

image.png

2.2 redis读写流程

  • client链接server,发起发送cluster nodes请求;
  • server返回集群拓扑,主要包括集群节点及槽位跟节点之间得映射关系,客户端在内存中缓存集群拓扑
  • 客户端读写数据时,根据hash(key)%16384计算得到key归属得槽位,再查询槽位跟节点得映射,进一步得到key归属的节点server2,直接访问节点进行读写
  • server2收到客户端的请求,检查自身是否为key归属的节点;若不是则响应告知客户端client重定向到server3;若是则直接返回业务操作结果;
  • 客户端收到重定向响应,重新向server3发起读写请求
  • server3收到请求,重复第4步操作

image.png

2.3 redis的特性

2.3.1 多数据库

  • 每个数据库对外都是以一个从0开始的递增命名数据库,不支持自定义命名
  • redis默认支持16个数据库,可以通过调整database参数来修改这个默认值
  • redis默认选择的是0号数据库
  • SELECT 数字可以切换数据库
  • 多个数据库之间不是完全隔离的,比如flushall命令范围是所有数据库
  • flushall清空redis实例下所有数据库数据
  • flashdb清空当前数据库的数据

2.3.2 redis基础命令

  • 获得符合规则的key名称
    • keys 表达式 (?,*,[],\?)
  • 判断一个key是否存在
    • exists key
  • 删除key
    • del key
    • del key1 key2
  • 获取键值的数据类型
    • 返回值类型(string,hash,list,set,zset)
  • redis命令不区分大小写

2.4 redis数据类型

2.4.1 string

字符串类型是redis中最基本的数据类型,它能够存储任何形式的内容。一个字符串类型的值存储的最大容量是1GB

命令作用
set设置指定键的值
get获取指定键的值
setnx将键的值设置为指定的值,如果这个键不存在,
那么SETNX命令将创建这个键并设置其值
mset一次性设置多个键的值
mget一次性获取多个键的值
incr键的值自增1
decr键的值自减1
incrby将键的值加上指定的增量值
decrby将键的值减少指定的增量值
incrybyfloat键所储存的值加上浮点数增量
append将指定的字符串追加到键所储存的值的末尾
strlen获取指定键所储存的字符串值的长度

2.4.2 hash

  • hash类型的值存储了字段和字段值的映射,字段和字段值只能是字符串,不支持其他数据类型,hash类型的键至多可以存储四个字节的数据
  • hash类型适合存储对象
  • redis可以为任何键增减字段而不影响其他键
命令作用
hset将哈希表中的一个字段的值设置为指定的值
hget获取哈希表中指定字段的值
hmset设置哈希表的多个字段值
hmget获取哈希表的多个字段值
hgetall返回哈希表中所有字段和值
hexists查看哈希表key中,给定域field是否存在
hincreby为哈希表中的字段值加上指定增量值,增量可以为负数
hdel删除指定的哈希表key
hkeys获取哈希表中的所有字段名
hvals获取哈希表中的所有字段值
hlen获取哈希表中字段数量

2.4.3 list

list是一个有序的字符串列表,列表内部实现是使用双向链表实现的

命令作用
lpush将一个或多个值插入到列表头部
rpush将一个或多个值插入到列表尾部
lpop移除并返回列表的头元素
rpop移除并返回列表的尾元素
llen返回列表的长度
lrange返回列表中指定区间的元素
lrem删除列表中等于给定值的元素  (lrem key count value) count为要删除的元素个数;
count > 0时从表头开始向表尾搜索,移除与value相等的元素,数量为count;
count < 0时从表尾开始向表头搜索,移除与value相等的元素,数量为count绝对值;
删除列表中所有与value相等的元素;
lindex通过索引获取列表中的元素
lset通过索引设置列表中的元素
ltrim只保留指定区间内的元素,其他元素删除
linsert在列表的元素前或元素后插入元素
rpoplpush移除列表最后一个元素并将该元素添加到另一个列表

2.4.4 set

set集合中的元素不重复且无序,一个集合可以存储2的32次方-1个元素

命令方法
sadd将一个或多个元素插入到集合中
smembers获取集合中所有元素
srem移除集合中的一个或多个元素
sismember判断元素是否在集合中
sdiff求集合的差集
sinter求集合的交集
sunion求集合的并集
sdiffstore求集合的差集并存储在指定集合中
sinterstore求集合的交集并存储在指定集合中
sunionstore求集合的并集并存储在指定集合中
scard返回集合中元素的数量
spop移除集合中一个或多个随机元素
srandmember获取返回一个集合中的随机元素,srandmember key count
1、如果count为正数,且小于集合基数,那么返回一个包含count个元素的数组,
数组中的元素各不相同
2、如果count大于等于集合基数,那么返回整个集合
3、如果count为负数,那么返回一个数组,数组中的元素可能会重复出现多次,
而数组的长度为count的绝对值

2.4.5 sorted set

有序集合,在集合的基础上为每个集合关联了一个分数以便于获取分数最高的TOP N个元素

命令作用
zadd将一个或多个成员及其分数插入到有序集合中
zscore返回有序集合中成员的分数值
zrange返回有序集中指定范围的成员,成员位置按分数递增
zrevrange返回有序集中指定范围的成员,成员位置按分数递减
zrangebyscore返回有序集合中分数值位于指定区间内的成员
zincrby给有序集合中指定成员的分数值加上指定的增量
zcard计算集合中的成员个数
zcount计算有序集合中指定分数区间的内的成员数量
zrem移除有序集合中一个或多个元素
zremrangebyrank移除有序集合中指定排名区间内的成员
zremrangebyscore移除有序集合中,分数在指定区间内的成员

2.5 redis中键的生存时间

使用expire命令设置一个键的生存时间,到期后redis会自动删除这个键

命令作用
expire以秒为单位设置key的过期时间
pexpire以毫秒为单位设置key的过期时间
ttl查看key的剩余过期时间,以秒为单位
pttl查看key的剩余过期时间,以毫秒为单位
persist移除指定key的过期时间,这样key就永不过期
expireat设置时间戳(秒)对应的时间为key的过期时间
pexpireat设置时间戳(毫秒)对应的时间为key的过期时间

下面是几个常见应用场景

  • 限时的优惠活动信息
  • 网站数据缓存(缓存定时更新的数据)
  • 限制网站访客访问频率(限制一分钟只能访问十次)

2.6 redis管道

Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应,管道在客户端使用,redis本身没有管道操作命令

2.7 redis中的数据排序

对列表、集合、有序集合键的值进行排序

  • SORT key。默认以数字作为对象,值被解释为双精度浮点数,然后进行比较
  • SORT key BY pattern。根据模式进行排序
  • SORT key LIMIT start count。限制返回的数量
  • SORT key GET pattern。获取排序后的元素
  • SORT key ASC|DESC。可指定排序方式为升序或降序
  • SORT key ALPHA。将元素解释为字符串进行排序
  • SORT key STORE dstkey。将排序后的结果存储到dstkey中

2.8数据持久化

redis支持两种持久化方式

2.8.1 RDB

RDB是redis默认的持久化方式

  • RDB通过快照的方式完成持久化,当符合一定条件时,redis会将内存中的所有数据执行快照操作并存储到硬盘,默认存储在dump.rdb文件中
  • redis进行快照的时机(可以在redis.conf中)
    • save 900 1:表示900s内至少一个键被更改则进行快照
    • save 300 10
    • save 60 10000
  • 手动执行save或者bgsave命令让redis执行快照
    • save由主进程执行快照,会阻塞其他请求
    • bgsave是由redis执行fork函数复制出一个子进程来执行快照

2.8.2 AOF

  • AOF持久化方式通过日志文件的方式实现,通过配置appendonly参数开启
    • 设置appendonly yes
  • redis写命令同步的时机
    • appendfsync always:每次都会执行
    • appendfsync everysec: 默认每一秒执行一次同步操作
    • appendsync no:不主动进行同步,由操作系统来做,30s一次
  • RDB切换到AOF
    • config set appendonly yes
    • config set save "" eg:config set save "60 10000"

注意:

  • redis启动时,如果同时开启了RDB和AOF,redis会优先使用AOF的方式来恢复数据,因为AOF方式保存的数据完成性较高,如果AOF文件丢失了,则启动后数据库内容为空
  • 如果把正在运行的redis持久化方式由RDB修改为AOF,建议先使用动态切换方式,在修改配置文件(如果直接修改文件在重启数据库,数据库就为空了)
  • RDB方式故障时,会丢失最后一次快照之后的数据

三、redis优化

  • 精简键名和键值
    • 键名:尽量精简,但也不能为了节约空间而使用不易理解的键名
    • 键值:部分键值考虑使用数字来表示,如男/女
  • 当业务场景不需要持久化时,关闭持久化方式会获得更高的性能
  • 内部编码优化
    • redis为每种数据类型都提供了两种内部编码方式,在不同的情况下redis会自动调整合适的编码方式
  • SLOWLOG
    • slowlog-log-slower-than 它决定要对执行时间大于多少微妙的命令进行记录
    • slowlog-max-len 决定slowlo最多能保存多少条日志
  • 修改linux内核内存分配策略
    • overcommit_memory是一个 Linux 系统设置,它控制着内核在内存分配方面如何处理失败的内存分配请求。如果系统中的空闲内存不足,内核会尝试分配更多的内存。如果分配失败,内核会根据 overcommit_memory 的设置来决定如何处理
      • 0:内核会尝试分配请求的内存,如果分配失败,会返回错误。这是默认值
      • 1:内核会尝试分配请求的内存,如果分配失败,它会尝试使用内存清理算法来腾出更多的内存。这通常会成功,但可能会影响到正在运行的进程,因为内存清理算法会结束一些进程以释放内存
      • 2:内核会立即返回错误,如果请求的内存无法立即分配。这可以防止系统过度消耗内存
    • 向etc/sysctl.conf添加vm.overcommit_memory=1,重启服务器
    • 或执行sysctl vm.overcommit_memory立即生效
  • 关闭transparent huge pages(THP)
    • THP会造成内存锁影响redis性能,建议关闭
      • Transparent Huge Pages用来提升内存管理的性能
      • Transparent Huge Pages在32位的HEL6中不支持
    • 使用root用户执行下面的命令关闭
      • echo never > /sys/kernel/mm/transparent_hugepage/enabled
      • 把这条命令添加到这个文件/etc/rc.local
  • 修改linux中TCP最大连接数
    • 此参数确定了TCP链接中已完成队列的长度,此值小于等于linux系统中定义的/proc/sys/net/core/somaxcoon值,redis默认是511,linux默认参数是128,当系统开发量大且客户端速度缓慢的时候,可以将这两个参数一起参考设定
    • echo 511 > /proc/sys/net/core/somaxcoon
    • 这个参数并不是限制redis的最大连接数,redis最大连接数通过maxclients参数控制,默认的最大连接数是10000
  • 限制redis的内存大小
    • 通过redis的info命令查看内存使用情况
    • 如果不设置maxmemory或设置为0,64位系统不限制内存,32位系统最多使用3GB内存
    • 修改配置文件中maxmemoey和maxmemory-policy
      • maxmemory:最大内存
      • maxmemory-policy: 内存不足时,数据删除策略
  • 数据总量不大且内存足够的情况下不需要限制redis的内存大小,如果数据量不可预估且内存有限,尽量限制redis使用的内存大小,这样可以避免redis使用swap分区或出现OOM错误
  • 注意:如果不限制内存,当物理内存使用完之后,会使用swap分区,这样性能较低,如果限制了内存,当达到指定内存之后就不添加数据了,否则会报OOM错误,可以设置maxmemory-policy,内存不足时删除数据
  • redis是个单线程模型,客户端命令过来后按顺序执行,如果想要一次操作多条数据的时候,可以使用管道或者使用一次可以操作多条数据的命令

参考

redis菜鸟教程

Redis内存数据库_在线课程_华为云开发者学堂_云计算培训-华为云 (huaweicloud.com)


标题:大数据基础--redis
作者:wenyl
地址:http://www.wenyoulong.com/articles/2023/11/02/1698903607963.html