目录
学习计划
- Redis的介绍、优缺点、使用场景
- Linux中的安装
- 常用命令
- Redis各个数据类型及其使用场景
- Redis字符串(String)
- Redis哈希(Hash)
- Redis列表(List)
- Redis集合(Set)
- Redis有序集合(sorted set)
- Redis - 瑞士军刀
- 慢查询
- pipeline流水线
- 发布订阅
- bitmap
- HyperLogLog算法
- GEO
- Redis持久化,数据备份与恢复
- 高可用
- Redis安全如何保证
- Redis性能测试
- 整理自己的RedisUtil https://www.runoob.com/redis/redis-java.html
- Redis面试题汇总
- https://www.w3cschool.cn/redis/redis-ydwp2ozz.html
- 系列文章 https://www.cnblogs.com/jack1995/category/1076657.html
- Redis常用客户端总结
- Redis实战使用场景
学习笔记
Redis的介绍、优缺点、使用场景
- Redis是什么: 开源的,基于键值的存储服务系统,支持多种数据类型,性能高,功能丰富
- 特性(主要有8个特性):
- 速度快:官方给出的结果是10W OPS,每秒10W的读写(为什么是10W,因为内存的相应时间是100纳秒-10万分之一秒)。数据存储在内存中;使用C语言开发;Redis使用单线程,减少上下文切换。本质原因是计算机存储介质的速度,内存比硬盘优几个数量级)。MemoryCache可以使用多核,性能上优于Redis。
- 持久化:Redis所有的数据保持在内存中,对数据的更新将异步地保存到磁盘上。断掉,宕机? RDB快照/AOF日志模式来确保。MemoryCache不提供持久化
- 多种数据结构:Redis提供字符串,HashTable, 链表,集合,有序集合;另外新版本的redis提供BitMaps位图,HyperLogLog超小内存唯一值计数,GEORedis3.2提供的地理位置定位。相比memocache只提供字符串的key-value结构
- 支持多种编程语言:Java,PHP,Ruby,Lua,Node
- 功能丰富: 发布订阅,支持Lua脚本,支持简单事务,支持pipline来提高客户端的并发效率
- 简单:单机核心代码23000行,让开发者容易吃透和定制化;不依赖外部库;单线程模型
- 主从复制:主服务器的数据可以同步到从服务器上,为高可用提供可能
- 高可用、分布式:2.8版本后提供Redis-Sentinel支持高可用;3.0版本支持分布式
- 典型应用场景:
- 缓存系统:缓存一些数据减少对数据库的访问,提高响应速度
- 计数器:类似微博的转发数,评论数,incr/decr的操作是原子性的不会出错
- 消息队列系统:发布订阅的模型,消息队列不是很强
- 排行版: 提供的有序集合能提供排行版的功能,例如粉丝数,关注数
- 实时系统:利用位图实现布隆过滤器,秒杀等
安装
- Linux中安装
wget http://download.redis.io/releases/redis-5.0.7.tar.gz tar -zxvf redis-5.0.7.tar.gz mv redis-5.0.7 /usr/local/redis 不需要先创建/usr/local.redis文件夹 cd /usr/local/redis make make install vi redis.conf * bind 0.0.0.0 开发访问 * daemonize yes 设置后台运行 redis-server ./redis.conf 启动 redis-cli 进入命令行,进行简单的命令操作 vi redis.conf > requirepass password 修改密码 redis-cli 再次进入cmd > shutdown save 关闭redis,同时持久化当前数据 redis-server ./redis.conf 再次启动redis redis-cli 进入命令行 > auth password 将redis配置成系统服务,redis/utils中自带命令,我们只需修改参数 /usr/local/redis/utils/./install_server.sh [root~ utils]# ./install_server.sh Welcome to the redis service installer Please select the redis port for this instance: [6379] 默认端口不管 Selecting default: 6379 Please select the redis config file name [/etc/redis/6379.conf] /usr/local/redis/redis.conf 修改配置文件路径 Please select the redis log file name [/var/log/redis_6379.log] /usr/local/redis/redis.log 修改日志文件路径 Please select the data directory for this instance [/var/lib/redis/6379] /usr/local/redis/data 修改数据存储路径 Please select the redis executable path [/usr/local/bin/redis-server] Selected config: Port : 6379 Config file : /usr/local/redis/redis.conf Log file : /usr/local/redis/redis.log Data dir : /usr/local/redis/data Executable : /usr/local/bin/redis-server Cli Executable : /usr/local/bin/redis-cli chkconfig --list | grep redis 查看redis服务配置项 redis_6379 0:off 1:off 2:on 3:on 4:on 5:on 6:off 服务名是redis_6379
- 可执行文件说明
- redis-server: Redis服务器,启动Redis的
- redis-cli: Redis命令行客户端连接
- redis-benchmark: 对Redis做性能测试
- redis-check-aof: AOF文件修复工具
- redis-check-dump: RDB文件检查工具
- redis-sentinel: Sentinel服务器(2.8以后)
- 启动方式
- redis-server: 最简单的默认启动,使用redis的默认参数
- 动态参数启动:redis-server --port yourorderpoint
- 配置文件的方式: redis-server configpath
- 比较:
- 生产环境选择配置启动;单机多实例配置文件可以选择配置文件分开
- Redis客户端返回值
- 状态回复:ping->pong
- 错误恢复:执行错误的回复
- 整数回复:例如incr会返回一个整数
- 字符串回复: get
- 多行字符串回复:mget
- 常用配置
- daemonize: 是否是守护进程(y/n)
- port端口:默认是6379
- logfile:Redis系统日志
- dir:Redis工作目录
- 常用命令:在线练习http://try.redis.io/
redis-cli -h x.x.x.x -p x 连接 auth "password" 验证密码 redis-cli --raw可以避免中文乱码 exit 退出 select index 切换到指定的数据库 keys * 显示所有key,如果键值对多不建议使用,keys会遍历所有key,可以在从节点使用;时间复杂度O(N) dbsize 算出所有的key的数量,只是数量;时间复杂度O(1) exists key key是否存在,存在返回1,不存在返回0;时间复杂度O(1) incr key 将key的值加一,是原子操作 decr key 将key的值加一,会出现复数,是原子操作 del key 删除key,删除成功返回1,失败返回0;时间复杂度O(1) expire key seconds 设置过期时间,过期之后就不存在了;时间复杂度O(1) ttl key 查看key剩余的过期时间,key不存在返回-2;key存在没设置过期时间返回-1;(TTL Time To Live) persist key 去掉key的过期时间,再查看ttl key,返回值是-1,表示key存在并且没有设置过期时间 type key 查看类型;时间复杂度O(1) config get * 获取配置信息 set key value插入值 sadd myset 1 2 3 4 插入set get key获取值 del key删除key cat redis.conf | grep -v "#" | grep -v "^$" 查看配置文件,去除所有的#,去除所有的空格 setnx key value #key不存在,才设置 set key value xx #可以存在,才设置 set key value [exporation EX seconds | PX milliseconds] [NX|EX] mget key1 key2 key3 批量获取 1次mget=1次网络时间+n次命令时间;时间复杂度O(n) mset key1 value1 key2 value2 批量插入;时间复杂度O(n) n次get = n次网络时间 + n次命令时间,mget一次就能完成,省去大量的网络时间 getset key newvalue # set key newvalue并返回旧的value append key value #将value追加到旧的value strlen key #获取value的长度,中文占2个字节 incrbyfloat key 3.5 #增加key对应的值 set/get/del, incr(自增1)/decr(自减1)/incrby(incrby key n自增n)/decrby getrange key start end #获取value从start到end的值 setrange key index value #设置指定下标为一个新的值 hset key field value #给key的field设置值 hget key field #获取key的field的值 hdel key field #删除key的field的值 hgetall key #获取key的所有值 hexists key field # 判断key的field是否存在 hlen key #获取key field的数量 hmset key field1 value1 field2 value2 hmget key field1 field2 hsetnx/hincrby/hdecry/hincrbyfloat lpush key value1 value2...valueN #从左边插入 rpush key value1 value2...valueN #从右边插入 linsert key before|after value newValue rinsert key before|after value newValue lpop key #从左边弹出一个item rpop key #从右边弹出一个item lrem key count value #若count等于0或者不填,表示删除所有的value值相等的item;若count>0,表示从左到右删除最多count个value相等的item;若count<0,表示从右到左,删除最多Math.abs(count)个value相等的项 ltrim key start end #按照索引范围修剪列表,可以用来慢删除,因为全删除可能会阻塞redis lrang key start end #获取key中从start到end的值 lindex key index #取第index的值 llen key #算出列表的长度 lset key index newValue #修改index的值为newValue blpop key timeout #lpop阻塞版本,timeout是阻塞时间,timeout=0表示死等,lpop会立马返回,有时候数据更新不那么及时,或者消息队列中消息未及时处理,我们可以使用这个 brpop key timeout lpush + LPOP = STACK lpush + RPOP = QUEUE lpush + ltrim = 有序的集合 lpush + rpop = 消息队列 sadd key value #不支持插入重复元素,失败返回0 srem key element #删除集合中的element元素 smembers key #查看集合元素 sinter key1 key2 #取出相同:交集 sdiff key1 key2 #取出key1中key2没有的元素:差集 sunion key1 key2 #取出二者所有的元素:并集 sdiff|sinter|sunion store key #将结果存到key中,有时候计算一次耗时 scard key #计算集合大小 sismember key element #判断element是否在集合中 srandmember #返回所有元素,结果是无序的,小心使用,可能结果很大 smembers key #获取集合中的所有元素 spop key #从集合中随机弹出一个元素 scan SADD = Tagging SPOP/SRANDMEMBER = Random item SADD + SINTER = Social Graph zadd key score element #添加score和element O(logN): 使用xx和跳表的数据结构 zrem key element #删除元素 zscore key element #返回元素的分数 zincrby key increScore element #增加或减少元素分数 zcard key #返回元素的总个数 zrank key element #获取element的排名 zrange key start end [withscores] #返回指定索引范围内的升序元素 zrangebyscore key minScore maxScore [withscore] #返回分数在minScore和maxScore之间的元素 zcount key minScore maxScore #返回有序集合内在指定分数范围内的个数 zremrangebyrank key start end #删除指定排名内的元素 zremrangebyscore key minScore maxScore #删除指定分数内的元素 zrevrang/zrevrange/集合间的操作zsetunion info replication 查看分片,能够获取到主从的数量和状态 config get databases 获取所有数据库
数据结构和内部编码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-86qRnZ3y-1613619964700)(png/redis-data-type-structure.PNG)]
- Reids支持5中存储的数据格式: String, Hash, List, Set, Sorted Set
-
string
- redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象,最大能存储 512MB。
- 使用场景:缓存/计数器/分布式锁/Web集群session共享/分布式系统全局序号(不用每次都拿,一次拿1000个放到内存中)…
- 常用命令:
- 实战:实现分布式的id生成器,可以使用incr的思路,但是实际中会比这复杂
-
hash
- 是一个键值(key=>value)对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
- 实战:统计用户主页的访问量, hincrby user:1:info pageview count
- Redis集群架构下不太适合
-
list
- Redis 列表是简单的字符串列表,按照插入顺序排序。列表最多可存储
-