redis基础
1. 简介
Redis 也称为远程字典服务,是完全开源的,使用ANSIC语言编写遵守BSD协议,是一个高性能的Key-Value数据库,提供了丰富的数据结构,例如String、Hash、List、Set、SortedSet等等。数据是存在内存中的,同时Redis支持事务、持久化、LUA脚本、发布/订阅、缓存淘汰、流技术等多种功能特性提供了主从模式、Redis Sentinel和Redis Cluster集群架构方案。
1.主流功能与应用
- 分布式缓存,挡在mysql数据库之前的带刀护卫
- 所有查询先去找redis,查得到就直接返回,找不到就去访问MySQL,mysql返回数据以后,就把该数据写到redis,下次客户端在查询该数据,就可用直接在redis上查到了。
- 内存存储和持久化(RDB+AOF),redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- redis活着的时候,所有数据都是在内存(memory)的,但断电后,redis里面的数据就会丢失,那又要把mysql的数据重新加载进redis?这样的工作会比较烦躁,所以redis自己也带有数据持久化功能,当redis关机了,在内存中的redis数据可以写进硬盘,那么当redis恢复使用后,就可以把硬盘上的东西重新读回到redis,依旧不麻烦mysql。
- 高可用架构搭配
- 单机、主场、哨兵、集群
- 缓存穿透、击穿、雪崩
- 避免一台redis挂了,所有查询都找mysql
- 分布式锁
- 队列
2.redis与传统数据库(mysql)的关系
- Redis是Key-Value数据库(NoSQL一种),mysql是关系数据库
- Redis数据操作主要在内存,而mysql主要存储在磁盘
- Redis在某一些场景使用中要明显优于mysql,比如计数器、排行榜等方面
- Redis通常用于一些特定场景,需要与Mysql一起配合使用
- 两者并不是相互替换和竞争关系,而是共用和配合使用
3.redis优势
- 性能极高,Redis能读的速度是110000次/秒,写的速度是81000次/秒
- Redis数据类型丰富,不仅仅支持简单的Key-Value类型的数据,同时还提供list、set、zset、hash等数据结构的存储
- Redis支持数据持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- Redis支持数据的备份,即master-slave模式的数据备份
4.总结图
5.官网地址
中文:
6.Redis源码地址:https://github.com/redis/redis
7.Redis在线测试:https://try.redis.io
8.Redis命令参考:http://doc.redisfans.com
2. 安装使用
1.下载地址:https://github.com/tporadowski/redis/releases。
2.下载完后,解压文件,在该文件目录下redis.windows.conf
文件中可以修改端口和密码。
3.启动服务器:在该目录下的终端执行redis-server.exe redis.windows.conf
。
2.1 Redis客户端
安装完成Redis,我们就可以操作Reids,实现数据的CRUD了。这需要用到Redis客户端,包括:
- 命令行客户端
- 图形化桌面客户端
- 编辑客户端
1.命令行客户端
Redis安装完成后就自带了命令行客户端:redis-cli,使用方式如下:
1 | redis-cli [option] [commonds] |
其中常见的options有:
-h 127.0.0.1
:指定要连接的redis节点的ip地址,默认是127.0.0.1-p 6279
:指定要连接的redis节点的端口,默认是6379-a 123456
:指定redis的访问密码
其中的commonds就是Redis的操作命令,例如:
ping
:与redis服务端做心跳测试,服务端正常会返回pong
不指定commond时,会进入redis-cli的交互控制台。
注意:如果在文件目录下的控制台直接输入redis-cli.exe -h 127.0.0.1 -p 6380 -a 123456
会出现提醒,提醒这样输入密码会有风险,所以可以通过如下命令完成:
1 | redis-cli.exe -h 127.0.0.1 -p 6380 |
3. 常见命令
3.1 Redis数据结构介绍
Redis是一个Key-Value的数据库,Key一般是String类型,不过value的类型多种多样:
类型 | 描述 |
---|---|
string | hello world |
Hash | {name: “jack”, age: 21} |
List | [A -> B -> C -> C] |
Set | {A, B, C} |
SortedSet | {A: 1, B: 2, C: 3} |
GEO | {A: (120.3, 30.5)} |
BitMap | 0110110101110101011 |
HyperLog | 0110110101110101011 |
其中,前面5种是基本类型,后面3种是特殊类型。
Redis为了方便我们学习,将操作不同的数据类型的命令也做了分组,在官网https://redis.io/commands可以查看到不同的命令。
3.2 Redis通用命令
通用指令是部分数据类型的,都可以使用的指令,常见的有:
help:查看一个命令的具体用法,例如:help keys
keys:查看符合模板的所有Key,不建议在生产环境设备上使用(底层是模糊查询的机制,当数据量过大时,会给cpu很大的负担,会搜索很长的时间,而redis是单线程的,那么搜索这段时间就不会执行其它程序)
- 查询所有匹配的keys:
keys *
- 查询以a开头的所有的keys:
keys a*
- 查询所有匹配的keys:
del:删除一个指定的key
- 删除name这个key:
del name
- 删除name这个key:
exists:判断key是否存在,存在返回1,不存在就返回0
- 判断name这个key是否存在:
exists name
- 判断name这个key是否存在:
expire:给一个key设置有效期,有效期到期时,该key会被自动删除
- 给age这个key设置20秒的有效期:
expire age 20
- 给age这个key设置20秒的有效期:
ttl:查看一个key的剩余有效期,当返回-2时,说明该key已经不存在了
- 查看age这个key的剩余有效期:
ttl age
- 当创建的key没有指定有效期时,通过ttl查询会返回-1,表示该key会永久有效。
- 查看age这个key的剩余有效期:
3.3 String类型
String类型,也就是字符串类型,是Redis中最简单的存储类型
其value是字符串,不过根据字符串的格式不同,又可以分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以自增、自减操作
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m。
KEY | VALUE |
---|---|
msg | hello world |
num | 10 |
score | 92.5 |
1.String类型的常见命令:
- set:添加或者修改已经存在的一个String类型的键值对
- get:根据key获取String类型的value
- mset:批量添加多个String类型的键值对
- mget:根据多个key获取多个String类型的value
- incr:让一个整型的key自增1
- incrby:让一个整型的key自增并指定步长,例如:incrby num 2 让num的值自增2
- incrbyfloat:让一个浮点类型的数字自增(必须指定步长)
- setnx:添加一个String类型的键值对,前提是这个key不存在,否则不执行(修改不成功)
- setex:添加一个String类型的键值对,并且指定有效期
- 添加一个key为name,value为jack,有效期为10s的数据:
setex name 10 jack
- 添加一个key为name,value为jack,有效期为10s的数据:
Redis没有类似Mysql中Table的概念,那该如何区分不同类型的key?
2.key的结构
Redis的key允许有多个单词形成层级结构,多个单词之间用:
隔开,格式如下:
项目名:业务名:类型:id
这个格式并非固定,也可以根据自己的需求来删除或添加词条
例如项目名称叫heima,有user和product两种不同类型的数据,可以这样定义key:
- user相关的key:heima:user:1
- product相关的key:heima:product:1
如果value是一个java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
KEY | VALUE |
---|---|
heima:user:1 | {“id”: 1, “name”: “jack”, “age”: 21 } |
heima:product:1 | {“id”: 1, “name”: “小米11”, “price”: 4999} |
例子:
3.4 Hash类型
Hash类型,也叫散列,其中value是一个无序字典,类似于java中的HashMap结构。
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便:
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:
1.Hash类型的常见命令:
hset key field value:添加或者修改hash类型key的field的值
- 向heima:user:3里面的name添加值lucy:
hset heima:user:3 name lucy
- 向heima:user:3里面的age添加值21:
hset heima:user:3 age 21
- 向heima:user:3里面的name添加值lucy:
hget key field:获取一个hash类型key的field的值
hmset:批量添加多个hash类型key的field的值
- 使用:
hmset heima:user:4 name lilei age 20 sex man
- 使用:
hmget:批量获取多个hash类型key的field的值
- 使用:
hmget heima:user:4 name age sex
- 使用:
hgetall:获取一个hash类型的key中的所有的field和value
hkeys:获取一个hash类型的key中的所有的field
hvals:获取一个hash类型的key中的所有的value
hincrby:让一个hash类型key的字段值自增并指定步长
使用(自增2):
hincrby heima:user:3 age 2
hsetnx:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行(修改不成功)
3.4 List类型
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和可以支持反向检索。
特征也与LinkedList类似:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用来存储一个有序数据,如朋友圈点赞列表、评论列表等。
List类型的常见命令
- lpush key element … :向列表左侧插入一个或多个元素
- 向users的列表左侧依次插入1、2、3:
Lpush users 1 2 3
- 向users的列表左侧依次插入1、2、3:
- lpop key :移除并返回列表左侧的第一个元素,没有则返回nil
- rpush key element … :向列表右侧插入一个或多个元素
- rpop key :移除并返回列表右侧的第一个元素,没有则返回nil
- lrange key start end :返回一段角标范围内的所有元素
- 向users的列表左侧依次取出下标1到3的元素():
lrange users 1 3
- 向users的列表左侧依次取出下标1到3的元素():
- blpop和brpop :与lpop和rpop类似,只不过在没有元素时等待指定时间,而不是直接返回nil
- 向users2中从左边移除元素,且等待时间为39秒:
blpop users2 39
- 向users2中从左边移除元素,且等待时间为39秒:
3.5 Set类型
Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个Hash表,因此具备与HashSet类似的特征:
- 无序
- 元素不可重复
- 查找快
- 支持交集、并集、差集等功能
Set类型的常见命令
- sadd key member … :向set中添加一个或多个元素
- srem key member … :移除set中的指定元素
- scard key :返回set中元素的个数
- sismember key member :判断一个元素是否存在于set中
- smembers:获取set中的所有元素
- sinter key1 key2 … :求key1和key2的交集
- sdiff key1 key2 … :求key1和key2的差集(key1中有,而key2中没有的元素)
- sunion key1 key2 … :求key1和key2的并集
3.6 SortedSet类型
Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别较大,SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加hash表。
SortedSet具备下列特性:
- 可排序
- 元素不重复
- 查询速度快
因此SortedSet的可排序特性,经常被用来实现排行榜这样的功能。
SortedSet类型的常见命令
- zadd key score member:添加一个或多个元素到sortedset,如果已经存在则更新其score值
- 使用:
zadd students 85 jack 83 kucy 95 tom
- 使用:
- zrem key member:删除sortedset中的一个指定元素
- 使用:
zrem students tom
- 使用:
- zscore key member:获取sortedset中的指定元素的score值
- zrank key member:获取sortedset中的指定元素的排名
- 使用:
zrank students rose
- 使用:
- zcard key:获取sortedset中的元素个数
- 使用:
zcard students
- 使用:
- zcount key min max:统计score值在给定范围内的所有元素的个数
- 使用:
zcount students 0 80
- 使用:
- zincrby key increment member:让sortedset中的指定元素自增,步长为指定的increment值
- 使用:
zincrby students 2 rose
- 使用:
- zrange key min max:按照score排序后,获取指定排名范围内的元素
- 如果是前三名:
zrevrange students 0 2
- 如果是前三名:
- zrangebyscore key min max:按照score排序后,获取指定score范围内的元素
- zdiff、zinter、zunion:求差集、交集、并集
注意:所有的排名默认都是升序的,如果要降序则在命令的Z后面添加rev即可
Redis官网中提供了各种语言的客户端,地址:https://redis.io/clients