目录
1、认识Redis
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
Redis能干嘛?
1、内存存储、持久化,内存中的数据是断电即失的,所以持久化很重要(RDB、AOF)
2、效率高,可以用于高速缓存
3、发布订阅系统
4、地图信息分析
5、计时器、计数器(浏览量)
6、……
特性
1、多样的数据类型
2、持久化
3、集群
4、事务
……
2、基础知识
1、redis默认有16个数据库,默认使用的是第0个数据库,可以使用select切换数据库
select 1 #切换1数据库
DBSIZE #查看DB大小
keys * #查看所有key
flushall #清空所有数据库
flushdb #清空当前数据库
exists key #判断当前key是否存在
move key 1 #移除当前的key
expire key second #设置过期时间
ttl key #查看key剩余过期时间
type key #查看key的类型
Redis是单线程的
官方表示,Redis是基于内存操作的,CPU不是Redis的性能瓶颈。Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程,就使用单线程了
Redis是C语言写的,官方提供的数据为100000+的QPS,完全不比同样使用key-value的MemeCache差
Redis为什么单线程还这么快?
误区1:高性能服务器一定是多线程的
误区2:多线程(CPU上下文切换)一定比单线程效率高
速度:CPU>内存>硬盘
核心:redis是将全部数据放在内存中,所以使用单线程去操作效率就是最高的,对于内存系统来说,如果没有上下文切换效率就是最高的,多次读写都是在一个CPU上。
3、Redis五大数据类型
1、String
set key value #设置key-value
get key #获取key的value
exists key #key是否存在
append key value #追加字符串,若key不存,相当于set key value
strlen key #获取字符串长度
incr key #当前key的value加1
decr key #当前key的value减一
incrby key 10 #当前key加10
decrby key 10 #当前key减10
getrange key 0 3 #字符串范围 (getrange key 0 -1 获取全部字符串)
setrange key 1 xx #替换指定位置开始的字符串
setex key second value #(set with expire)设置过期时间
setnx key value #(set if not with exists )不存在再设置 (分布式锁中常使用)
mset key1 v1 key2 v2 #批量设置
mget key1 key2 key3 #批量获取
msetnx key1 v1 key2 v2 #不存在再设置(批量 原子性操作 一起成功 一起失败)
getset key value #先获取原值再设置新值
127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> set name lqh
OK
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys * #查看所有的key
1) "age"
2) "name"
127.0.0.1:6379> EXISTS key
(integer) 0
127.0.0.1:6379> EXISTS name #判断当前key是否存在
(integer) 1
127.0.0.1:6379> move name 1 #将key移动到1号数据库中
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> set name 123
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> EXPIRE name 10 #设置key过期的时间,单位是秒
(integer) 1
127.0.0.1:6379> ttl name #查看当前key的剩余时间
(integer) 6
127.0.0.1:6379> set name lqh
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> TYPE name #查看当前key对应value的类型
string
127.0.0.1:6379> TYPE age
string
127.0.0.1:6379> set key1 v1 #设置值
OK
127.0.0.1:6379> get key1 #获得值
"v1"
127.0.0.1:6379> keys * #获得所有key
1) "key1"
2) "name"
3) "age"
127.0.0.1:6379> EXISTS key1 #判断某一个key是否存在
(integer) 1
127.0.0.1:6379> APPEND key1 "hello" #追加字符串,如果key不存在就相当于set key
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> APPEND key1 ",nihao"
(integer) 13
127.0.0.1:6379> STRLEN key1 #获取字符串长度
(integer) 13
127.0.0.1:6379> get key1
"v1hello,nihao"
#步长
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views #自增一
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views #自减一
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> INCRBY views 10 #设置步长,指定增量
(integer) 9
127.0.0.1:6379> DECRBY views 5 #设置步长,指定减量
(integer) 4
127.0.0.1:6379> get views
"4"
#字符串范围
127.0.0.1:6379> set key1 "hello,lqh" #设置key的值
OK
127.0.0.1:6379> get key1
"hello,lqh"
127.0.0.1:6379> GETRANGE key1 0 3 #截取字符串 [0,3]
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1 #获取全部的字符串 和get key是一样的
"hello,lqh"
#替换
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> SETRANGE key2 1 xx #替换指定位置开始的字符串
(integer) 7
127.0.0.1:6379> get key2
"axxdefg"
#setex key #(set with expire)设置过期时间
#setnx key #(set if not with exists )不存在再设置 在分布式锁中会常使用
127.0.0.1:6379> setex key3 30 "hello" #设置一个key3的值为hello,30秒后过期
OK
127.0.0.1:6379> ttl key3
(integer) 19
127.0.0.1:6379> setnx mykey "redis" #如果mykey不存在,创建mykey
(integer) 1
127.0.0.1:6379> keys *
1) "mykey"
2) "key1"
3) "key2"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> setnx mykey "hello" #如果mykey存在,创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
mset key1 v1 key2 v2 #批量设置
mget key1 key2 key3 #批量获取
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k2"
2) "k3"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3 #同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 #msetnx是一个原子性的操作,要么一起成功要么一起失败
(integer) 0
127.0.0.1:6379> get k4
(nil)
#对象
set user:1 {name:zhangsan,age:2} #设置一个user:1对象,值为json字符来保存一个对象
#这里的key是一个巧妙的设计:user:{id}:{filed},如此设计在redis中是完全ok的
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"
getset #先get再set
127.0.0.1:6379> getset db redis #如果不存在值则返回nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db Mongodb #如果存在值,获取原来的值并设置新的值
"redis"
127.0.0.1:6379> get db
"Mongodb"
数据结构是相同的
String类似的使用场景:value除了是我们的字符串还可以使我们的数字(计数器、统计多单位数量、粉丝数、对象缓存存储)
2、List
Redis中,可以将list用作栈、队列、阻塞队列的数据结构
所有list命令都是以l开头
lpush key v1 v2 ... #将一个值或多个值插入列表的头部(左)
rpush key v1 v2 ... #将一个值或多个值插入列表的尾部(右)
lrange key start end #用过区间获取具体的值 (0 -1 区间获取全部值)
lpop key #移除列表头部第一个值(左)
rpop key #移除列表尾部第一个值(右)
lindex key index #通过索引获取值
llen key #获取列表长度
lrem k