找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 文档 工具 设计
查看: 311|回复: 0

Redis的简单使用分享

[复制链接]

2万

主题

1249

回帖

2万

积分

超级版主

教育辅助界扛把子

附加身份标识
精华
1
热心
7
听众
1
威望
48
贡献
14307
违规
0
书币
49981
注册时间
2020-4-8

论坛元老灌水之王

发表于 2024-3-10 21:59 | 显示全部楼层 |阅读模式
emm 上次帮水友排查了一个redis 的问题。有水友留言想了解一下redis。我对redis的了解也不是很多一点点浅见分享给水友。希望水友能有收获。

Redis 是什么?
官方解释(https://redis.io/docs/about/): Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库、缓存、消息代{过}{滤}理和流引擎。Redis提供了数据结构,如字符串、哈希、列表、集合、排序集合、范围查询、位图、超日志、地理空间索引和流。Redis具有内置复制、Lua脚本、LRU驱逐、事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster提供高可用性和自动分区。


通俗解释(个人认为),Redis 是一款基于C语言开发的开源的内存数据库。它提供了丰富的数据(结构)类型 包括字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)和有序集合(sorted sets)、位图(bitmap)、地理空间索引(GEO)、流(stream) 等, 可以基于这些属于上述的数据(结构)类型,高效的满足我们的业务需求。


Redis 官网: https://redis.io/ (注意这里是.io域名)


版本差异
Redis 社区比较活跃,版本更新迭代非常快。截止到目前发文之前的版本是 Stable (7.2) 这里我们只拿出 5、6、7 三个版本简略说下差异,这里只说最核心的部分。详细对比差异请参考官网或网络。


redis 5  新的stream数据类型
redis 6  增加了多线程Thread I/O(工作线程还是单线程)  和 ACL细粒度的权限控制
redis 7 Redis Functions
Redis怎么使用? 可以用来做什么?
Redis 通常需要搭配一种开发语言来配合业务使用。如常见的开发语言都会有SDK 客户端。https://redis.io/docs/connect/clients/(官方clients)  也可以使用常见的桌面端开源图形客户端。
Redis 根据不同的业务需求,所能做的东西也不同 App后台服务端端业务、场景不同需求不同。下面我会举一些常见的业务需求场景 和 经典实现。
为什么要使用redis ?
Redis 基于内存操作数据,且是单线程原子操作(单个命令),因为单线程读写,避免了多线程并发冲突。早起redis 官方号称 单机redis qps为10w/s(和机器配置相关)
Redis桌面客户端
这种开源的桌面客户端连接工具非常的多,大家可以根据自己的喜好选择。我这里只介绍两款 两款都支持 支持Mac、Windows和Linux。
Tiny RDM
官网: https://redis.tinycraft.cc/zh/ (https://github.com/wailsapp/wails "https://redis.tinycraft.cc/zh/")
github: https://github.com/tiny-craft/tiny-rdm/releases (https://github.com/wailsapp/wails "https://github.com/tiny-craft/tiny-rdm/releases")

                               
登录/注册后可看大图

AnotherRedisDesktopManager
github:https://github.com/qishibo/AnotherRedisDesktopManager/releases

                               
登录/注册后可看大图

redis 安装
这里提供两种安装方式。
基于 Rethat Linux 发行版本的操作系统安装(yum)
yum install -y gcc tcl gcc-c++ make
yum install -y epel-release
yum install redis -y
上述命令执行完就已经安装好了。
打开配置文件:vim /etc/redis.conf
修改默认密码:查找 requirepass,默认密码为 foobared。需要修改

                               
登录/注册后可看大图

找到 bind 127.0.0.1 将其注释,否则redis只允许本机连接

                               
登录/注册后可看大图

找到 protected-mode yes 将其改为:protected-mode no

                               
登录/注册后可看大图

找到 port 6379 建议修改默认端口号

                               
登录/注册后可看大图

添加iptables 规则:
iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

                               
登录/注册后可看大图


Centos7 防火墙规则 :
firewall-cmd --zone=public --add-port=6379/tcp --permanent
firewall-cmd --reload
启动 : systemctl start redis

                               
登录/注册后可看大图


基于docker的方式安装,全平台通用前提是要装个docker。
1、docker pull redis:6.2.7

                               
登录/注册后可看大图

2、创建需要挂载的配置目录和文件
mkdir -p /data/redis6/conf
touch /data/redis6/redis.conf(这一步也可以先启动容器 从容器中copy出来一个。或者去dockerHub wget下来一个)
3、启动 docker run -p 6379:6379 --privileged=true --name redis6 -v /data/redis6/data:/data -v /data/redis6/conf/redis.conf:/etc/redis/redis.conf -d redis:6.2.7  redis-server /etc/redis/redis.conf

                               
登录/注册后可看大图

Redis 命令:
https://redis.io/commands/(官网)

                               
登录/注册后可看大图

每个命令都有示例 。可以根据数据类型筛选,过滤 首字母索引等。
以前有个中文版的现在找不到了

redis 常见的数据类型 和 经典实现
String:
      描述: 最基本的数据类型,二进制安全。不仅限于 存储 String。最大存储512M.
      ops: set [key,val] 会覆盖数据 get[key] incre[key]自增 setnx [key,val] 如果存在则返回,不存在则返回0。
      经典实现: 自增数实现分布式全局ID 各种访问数量,如 用户访问量,点赞。字符串用来存储 token , 短信验证码之类。
Hash(字典):
      描述: 存储类型类似于对象。hmset创建对象。 通过hget hset 获取对象。
      ops: hmset key [filed,val],[filed,val],[filed,val]. hget obj.filed. hset obj.filed
      经典实现: json序列化的对象存储,购物车实现。
List(列表):
      desc:  按照插入的String元素排序,后进先出 (stack)的数据结构。可以存储40亿成员。O(1) 复杂度
      ops: lpush [key,val]。 lrange [0 n] 取数据
      经典实现: 最新消息排行榜。
Set(集合):
      desc: 集合,类似于java List 无序,通过hash表实现。不允许重复。
      ops: sadd [key,val] 添加集合元素, smembers [key] 获取集合。
      SRANDMEMBER KEY :随机弹出集合中的一个元素
      SPOP KEY :随机删除弹出集合中的一个元素
      SCARD KEY : 集合中的元素个数
      经典实现:
        把关注人存在set中.可以 求交集、并集、差集。操作 计算共同关注。
        SPOP 、SRANDMEMBER 随机弹出元素可用于立即参与(微信)抽奖。(把用户id放入)
        SCARD 可用于显示多少人进行参加抽奖活动
        SCARD 点赞数量
StoreSet(Zset有序集合):
      desc:  会记录一个double类型的 score ,按照从小到达排序。score可以重复,Value不允许重复 分数小靠前。
      升序排列,分值越大越靠后,分值相同,则按照value的字典顺序排序
      ops:
      zadd key [NX|XX] [CH] [INCR] score member [score member ...]
      nx: member 必须不存在,才可以设置成功,用于添加
      xx: member 必须存在,才可以设置成功,用于更新
      ch: 返回此次操作后,有序集合元素和分数发生变化的个数
      incr: 对 score 做增加,相当于后面介绍的 zincrby
      zadd key score value [添加key]
      ZCARD key [获取一个排序的集合中的成员数量]
      zrange key 0,n(-1) [遍历集合 从小到大]
      zrevrange key 0,n(-1)[遍历集合 从大到小]
      zrangebyscore key 0,n(-1) limit x x[根据分数值查询,可选分页参数]
      zremrangebyscore key x x 删除有序set。
      经典实现:热搜排行榜(根据浏览点赞)、存储班级学生成绩排序。程序根据重要的任务排序,score 高的任务优先执行。
pub/sub(发布订阅)
      底层实现:
      Redis有两种发布/订阅模式:
        基于频道(Channel)的发布/订阅
        基于模式(pattern)的发布/订阅
      命令:
        #订阅 处于监听消息的状态
        SUBSCRIBE channels
        subscreibe user-topic
        #发布消息
        PUBLISH channels message
        publish user-topic hello
        # 查看当前订阅列表
        pubsub channels
BitMap
ops :   setbit key 1 1 ,getbit key 1, bitcount key
      经典实现: 统计打卡 、在线人数 、10亿手机号中判断重复
redis 具体使用场景(Redis 通常需要配合开发语言来完成业务。)
String 类型
存储 AccessToken  和 RefreshToken。
现在主流的web 或者app 与后端交互 登陆鉴权 的方式基本是 accessToken的形式。
用户登陆 服务端会 生成两个随机字符串  "access_token:a6f1efca84705b7041193f96f265ac768d35" 作为Key,
把用户的id 作为value 。设置过期时间为30min 后过期。
生成"refresh_token:e4e44f08754dadbfeec2927ee706cb01fa6b" 作为key ,把用户id 设置成value
设置过期时间为 1个月。
这样每次客户端发起请求携带access_token,后端从redis拿到并且校验,如果过期。则前端重新使用refresh_token换取 access_token。
set access_token:a6f1efca84705b7041193f96f265ac768d35 1  ex 1800

                               
登录/注册后可看大图

set refresh_token:e4e44f08754dadbfeec2927ee706cb01fa6b 1  ex 2626560

                               
登录/注册后可看大图

设置商品详情页,从程序中写入redis 中。

                               
登录/注册后可看大图


分布式自增ID (在分布式环境下保证id不重复)
set increment_id 1
INCR increment_id

                               
登录/注册后可看大图


Set 数据类型
公司年会简单的抽奖 把 公司所有人的姓名添加到 set 集合中。总共 有 3 等奖。 从
set 集合中随机弹出 3 个 做为 1 2 3 等奖。
sadd prize_user tom
sadd prize_user eric
sadd prize_user jack
sadd prize_user bob

                               
登录/注册后可看大图

SPOP prize_user
SPOP prize_user
SPOP prize_user

                               
登录/注册后可看大图

bitMap
有序大数据 去重 统计
假如 需要对一个亿的手机号判断是否有重复。在通常情况下我们会通过hash 来判断。这样不仅占用内存而且效率也不是特别高。我们可以把号码放到redis bitmap中。号码通常是11位第一位都是1 可以去调。这样还剩下 8位数字。bitmap 是一个数组具体存储的是bit位 0 和 1 。那么我们的号码就可以作为数组下标[index]最大为 99999999 的下标。下面我们就以131 开头的号码演示
setbit mobile_coll 3162587639 1
setbit mobile_coll 3162587611 1
setbit mobile_coll 3162587612 1
setbit mobile_coll 3162587613 1
setbit mobile_coll 3162587614 1
setbit mobile_coll 3162587615 1
setbit mobile_coll 3162587615 1

                               
登录/注册后可看大图

当我们第一次 放进去 13162587615 号码的时候返回0。我们再次放进去的时候就返回 1 说明该号码已经存在。时间复杂度为O(1) 且不占用内存。
bitMap 在线用户统计  把一些用户添加到 user_onlins 中 1表示在线 0表示下线 (online 单词好像拼错了undefined)
setbit user_onlins 132637 1
setbit user_onlins 132638 1
setbit user_onlins 132639 0
setbit user_onlins 132640 1
setbit user_onlins 132641 1
setbit user_onlins 132642 1

                               
登录/注册后可看大图

BITCOUNT user_onlins 统计 user_onlins 下的在线人数

                               
登录/注册后可看大图



分布式锁
如果我们的系统是分布式服务架构,调用操作系统内核加锁。已经不能保证并发安全。
举例子 52论坛中的签到功能,在0点的时候一个用户模拟发送了10个签到请求,如果该系统是分布式的情况下 10个请求 会被nginx 分发3台服务器。单个服务器中跑的代码加锁已经不能保证数据一致性。这个时候可以借助一个中间件来完成分布式锁的功能。保证在分布式集群环境下并发安全。
分布式锁的实现方式很多。借助的中间件也不限于Redis 主要是一种思想。在java生产环境中一般会使用 redisson 提供的分布式锁。或者zookeeper 来实现。

redis 内存8种淘汰策略(内存超过 maxmemory):
maxmemory-policy 可以指定配置使用下面哪一种淘汰策略。
     默认是no-eviction。内存满了写入OOM。
      1. volatile-lru:从已设置过期时间的数据集中挑选最近最少使⽤的数据淘汰。
      2. volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
      3. allkeys-lru:当内存不⾜以容纳新写⼊数据时,在键空间中,移除最近最少使⽤的 key(常用)
      4. allkeys-random:从数据集(server.db.dict)中任意选择数据淘汰。
      5. volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
      6. no-eviction:禁⽌驱逐数据,也就是说当内存不⾜以容纳新写⼊数据时,新写⼊操作会报错OOM。
      7. volatile-lfu:从已设置过期时间的数据集中挑选最不经常使⽤的数据淘汰。
      8. allkeys-lfu:当内存不⾜以容纳新写⼊数据时,在键空间中,移除最不经常使⽤的 key。


redis 删除策略(key过期删):
1、定时删除(时间换空间)
       节约内存,无占用,不分时段占用CPU资源,频度高
2、惰性删除(空间换时间)
       内存占用严重 延时执行,CPU利用率高
3、定期删除(折中)两种方式混合 Redis默认采用的就是该模式
       内存定期随机清理 每秒花费固定的CPU资源维护内存 随机抽查,重点抽查


ok~ 写的比较乱。。 凑合看吧。有问题可以在讨论哈 。

Great works are not done by strength, but by persistence! 历尽艰辛的飞升者,成了围剿孙悟空的十万天兵之一。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号


免责声明:
本站所发布的第三方软件及资源(包括但不仅限于文字/图片/音频/视频等仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢某程序或某个资源,请支持正版软件及版权方利益,注册或购买,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To: admin@cdsy.xyz

QQ|Archiver|手机版|小黑屋|城东书院 ( 湘ICP备19021508号-1|湘公网安备 43102202000103号 )

GMT+8, 2024-11-21 17:55 , Processed in 0.045514 second(s), 27 queries .

Powered by Discuz! CDSY.XYZ

Copyright © 2019-2023, Tencent Cloud.

快速回复 返回顶部 返回列表