关于Redis的知识点,你都学会了吗?1

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: Redis的介绍、优缺点、使用场景Linux中的安装常用命令Redis各个数据类型及其使用场景Redis字符串(String)Redis哈希(Hash)Redis列表(List)Redis集合(Set)Redis有序集合(sorted set)Redis - 瑞士军刀慢查询pipeline流水线发布订阅bitmapHyperLogLog算法GEORedis持久化,数据备份与恢复RDBAOFSpringBoot + Jedis + 1主2从3哨兵 实现Redis的高可用SpringBoot + Jedis + Redis Cluster代码案例高可用主

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 获取所有数据库

数据结构和内部编码

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 列表是简单的字符串列表,按照插入顺序排序。列表最多可存储 232 - 1 元素 (4294967295, 每个列表可存储40多亿)。

实战:微博按时间顺序展示消息

set


是 string 类型的无序集合,不允许插入重复元素,插入重复元素失败返回0。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

实战:抽奖系统(量不是很大的时候);like,star可以放到集合中;标签tag

zset


有序集合:有序且无重复元素,和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

实战:排行榜

Redis客户端: Java的Jedis(Socket通信),Python的redis-py


瑞士军刀

慢查询


生命周期

两点说明:


慢查询发生在第3阶段,比如keys *等这些需要扫描全表的操作

客户端超时不一定慢查询,但慢查询是客户端超时的一个可能因素

两个配置


slowlog-log-slower-than=n(微秒):命令执行时间超过x微秒,会被丢到一个固定长度的慢查询queue中;n<0表示不配置

slowlog-max-len: 先进先出的队列,固定长度,保存在内存中(重启redis会消失)

配置方法


默认值


config get slowlog-max-len=128

config get slowlog-log-slower-than=10000

修改配置文件重启


动态配置


config set slowlog-max-len 1000

config set slowlog-log-slower-than 1000

常用命令


slowlog get [n]:获取慢查询队列

slowlog len: 获取慢查询队列的长度

slowlog reset: 清空慢查询队列

运维经验


slowlog-max-len不要设置过大,默认10ms,通常设置1ms,根据QPS来设置

slowlog-log-slower-than不要设置过小,通常设置1000左右

定期持久化慢查询

pipeline流水线(批量操作)


当遇到批量网络命令的时候,n次时间=n次网络时间+n次命令时间。举个例子,北京到上海的距离是1300公里,光速是3万公里/秒,假设光纤传输速度是光速的2/3,也就是万公里/秒,那么一次命令的传输时间是 1300/20000*2(来回)=13毫秒, 什么是pipeline流水线,1次pipeline(n条命令)=1次网络时间+n次命令时间;pipeline命令在redis服务端会被拆分,因此pipeline命令不是一个原子的命令。注意每次pipeline携带数据量;pipeline每次只能作用在一个Redis节点上;M操作和pipeline的区别,M(mset)操作是redis的原生命令,是原子操作,pipeline不是原子操作


for(int i = 0; i < 10000; i++>) {
    jedis.hset(key, field, value); //1万次hset差不多要50秒
for(0->100) {
  Pipeline pipeline = jedis.pipelined();
  for(0->100) {
    pipeline.hset(key,field,value);
  }
  pipeline.syncAndReturnAll(); //拆分100次,每次100个命令,大概需要0.7秒
}

发布订阅:类似生产者消费者模型


角色:发布者(publisher),频道(channel),订阅者(subscriber); 发布者将消息发布到频道中,订阅者订阅相关的频道;

API: publish/subscribe/unsubscribe

publish channel message : publish sohu:tv “hello world”

subscribe sohu:tv

unsubscribe [channel]

psubscribe [pattern] #订阅模式 sohu*

bitmap:位图:数据量很大的时候节省存储内存,数据量小了,不节省


hyperloglog(算法,数据结构):


极小空间完成独立数量统计,本质是个string

api: pfadd key element[s]:向hyperloglog添加元素 pfcount key[s]:计算hyperloglog的独立总数 pfmerge key1 key2合并

GEO: 3.2提供的用于计算地理位置信息;数据类型是zset,可以使用zset的删除命令


使用场景:微信摇一摇看附近好友

api:

geo key longitude latitude member #增加地理位置信息

geopos key member[n] #获取地理位置信息

geodist key member1 membe2 [unit] m米 km千米 mi英里 ft尺 获取两地位置的距离

georadius #算出指定范围内的地址位置信息的集合,语法复杂了点

总结下Redis数据结构和类型的常见用法


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
|
存储 NoSQL 测试技术
关于redis涉及的知识点,C语言如何操作redis
关于redis涉及的知识点,C语言如何操作redis
|
10月前
|
存储 缓存 NoSQL
redis知识点
redis 知识点
63 0
|
11月前
|
存储 SpringCloudAlibaba 运维
Redis高级知识点总结
在 Redis 6.0 中,非常受关注的第一个新特性就是多线程。这是因为,Redis 一直被大家熟知的就是它的单线程架构,虽然有些命令操作可以用后台线程或子进程执行(比如数据删除、快照生成、AOF 重写),但是,**从网络 IO 处理到实际的读写命令处理,都是由单个线程完成的**。随着网络硬件的性能提升,Redis 的性能瓶颈有时会出现在网络 IO 的处理上,也就是说,单个主线程处理网络请求的速度跟不上底层网络硬件的速度
234 0
Redis高级知识点总结
|
10月前
|
缓存 监控 NoSQL
【Redis】Redis知识点阶段性总结 2
【Redis】Redis知识点阶段性总结
45 0
|
10月前
|
NoSQL Linux Redis
【Redis】Redis知识点阶段性总结 1
【Redis】Redis知识点阶段性总结
73 0
|
存储 缓存 监控
全新Redis6全部知识点,零基础入门3
全新Redis6全部知识点,零基础入门
12188 1
|
运维 NoSQL 网络协议
关于Redis的知识点,你都学会了吗?2
关于Redis的知识点,你都学会了吗?2
136 0
|
存储 缓存 监控
【Redis】回顾下Redis缓存击穿、缓存雪崩、缓存穿透知识点
Redis缓存击穿、缓存雪崩、缓存穿透知识点
108 0
【Redis】回顾下Redis缓存击穿、缓存雪崩、缓存穿透知识点
|
存储 缓存 NoSQL
Redis 跳表(skiplist)知识点详解
Redis框架从入门到学精(全)Python操作Redis从入门到精通附代码(全)Redis的常见面试题(全)一文读懂基于Redis的Amazon MemoryDB数据库科普下Redis数据类型中底层的数据结构(常考点)数据类型可以存储的值操作应用场景string字符串、整数或者浮点对整个字符串或者字符串的其中一部分执行操作,对整数和浮点数执行自增或者自减操作做简单的键值对缓存,计数器,共享session以及限速list列表。
155 0
Redis 跳表(skiplist)知识点详解
|
缓存 NoSQL 前端开发
【测试开发】知识点-项目中使用 Spring Cache + Redis 缓存数据
【测试开发】知识点-项目中使用 Spring Cache + Redis 缓存数据
【测试开发】知识点-项目中使用 Spring Cache + Redis 缓存数据