介绍: Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI 、C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库可用于数据库、缓存、消息中间件。
`
深入redis
(1)单线程redis为什么速度快?
1.redis是基于内存的,内存的读写速度非常快;
2.redis是单线程的,省去了很多上下文切换线程的时间;
3.redis使用多路复用技术,可以处理并发的连接(select poll epoll,redis现在使用epoll多路复制技术);
redis的瓶颈并不是cpu,而是系统的内存和网络的速度。
(2)redis-benchmark性能测试工具
在我们redis-server所在目录下使用该命令:
redis-benchmark -h localhost -p 6379 -c 100 -n 10000 //指定100个并发和10000个请求来测试现在redis的性能
![测试图片](http://dsvip1.vip/redis2.png)
(3)基础知识
五大基本数据类型
-
redis默认有16个数据库,默认使用的是第1个数据库db0。
select 0 #使用指定数据库
DBSIZE #查看db数据库内容个数
set key value #添加数据
keys * #查看所有的key值
flushdb #清空使用的数据库
flushall #清空所有数据库
exists key #判断一个key是否存在,存在返回1
move key 1 #将key移动到db1数据库中
del key #删除key
expire key 10 #为key设置一个过期时间,10s后key自动删除
ttl key #查看key剩余失效时间,默认为-1不失效
type key #查看key的类型
1、string类型
对于string类型我们可以使用这些命令:
append key value #在原来的key的值后面上面添加value,追加字符串。key不存在会生成新的key
strlen key #得到key值的长度
incr key #如果key值为整数可以实现+1操作
decr key #-1操作
incrby key 5 #一下+5操作
decrby key 5 #一下-5操作
--------------------------------------------------
本机redis:0>get views
"0"
本机redis:0>incr views
"1"
本机redis:0>incr views
"2"
---------------------------------------------------
获取范围值
getrange key 0 1 #获取key的索引0,1的值
setrange key 0 aa #将字符串从0索引开始修改值
本机redis:0>get name
"dlwan"
本机redis:0>setrange name 0 aa
"5"
本机redis:0>get name
"aawan"
---------------------------------------------------
setex key 10 value #设置key的过期时间10s
setnx key value #设置key(只有key不存在的时候才可以设置成功)
本机redis:0>setnx age 10 #再次设置返回0失败,可用于分布式锁
"1"
本机redis:0>get age
"10"
本机redis:0>setnx age 45
"0"
-----------------------------------------------------
批量操作
mset k1 v1 k2 v2 #批量设置key-value
mget K1 K2 #批量获取
msetex #批量设置
msetnx #保证原子性,要么都成功,否则就失败。
本机redis:0>keys *
1) "age"
2) "views"
3) "name"
本机redis:0>msetnx name dl names dll #设置name失败,所以names也失败
"0"
-----------------------------------------------------
getset key value #先获取在设置
-----------------------------------------------------
string类型我们可以用来计数器,多单位数字存储,用来存缓存
2、List类型
list是十分强大的,可以当栈、队列、堵塞队列来用。
插入数据
lpush key value #往列表的头部插入值(左)
lpop key #从列表的头部取值(左)
rpush key value #往列表的尾部插入值(右)
rpop key #往列表的尾部其取值(右)
lset key 0 value #更新下标为0的元素
-----------------------------------------------------------
范围获取
lrange key 0 1 #获取0到1列表中的值(从左开始)
lrange key 0 -1 #获取列表中的所有值
-----------------------------------------------------------
lindex key 0 #获取下标为0的列表的值
llen key #返回列表的长度
lrem key 2 value #移除两2个value
本机redis:0>lrange list 0 -1
1) "three"
2) "three"
3) "otwo"
4) "one"
本机redis:0>lrem list 2 three
"2"
本机redis:0>lrange list 0 -1
1) "otwo"
2) "one"
------------------------------------------------------------
ltrim key 0 1 #通过下标截取list指定长度,是永久截取的
linsert key after/before value1 value2#在list中的value1元素的前或者后插入值value2
本机redis:0>lrange mylist 0 -1
1) "hello"
2) "world"
本机redis:0>linsert mylist after hello wo
"3"
本机redis:0>lrange mylist 0 -1
1) "hello"
2) "wo"
3) "world"
list底层其实是由一个链表,可以充当强大的消息队列。
3、Set类型
存储无须不重复的数据,可以充当抽奖
sadd key value #添加数据
smembers key #查看数据
spop key #随机从集合中弹出(删除)元素
sismember key a #判断set集合中是否存在a元素
srem key value #移除set集合中的value元素
scard key #获取set集合中的元素个数
-------------------------------------------------------
srandmember key #随机获取set集合中的一个value,可用于抽奖活动。
srandmember key 2 #可以指定抽的个数
本机redis:0>srandmember myset
"g"
本机redis:0>srandmember myset
"b"
--------------------------------------------------------
sdiff key1 key2 #key1集合中与key2集合中不一样的元素(差集)
本机redis:0>smembers set1
1) "a"
2) "b"
3) "c"
本机redis:0>smembers set2
1) "d"
2) "f"
3) "c"
本机redis:0>sdiff set1 set2
1) "a"
2) "b"
sinter key1 key2 #获取key1集合中和key2集合中相同的元素(交集)
本机redis:0>sinter set1 set2
1) "c"
sunion key1 key2 #(并集)
-------------------------------------------------------
4、hash类型
hash类型实际就是一个map集合
hset key name value #保存数据到hash集合,name是map集合的key
hget key name #获取数据
hmset key name1 vlaue1 name2 value2 #批量保存数据
hmget key name1 name2 #批量获取数据
hgetall key #获取集合中所有的元素
hdel key name #删除hash集合的元素
hexists key name #判断hash中的key是否存在
hlen key #获取hash集合的长度
-----------------------------------------------------------------
hkeys key #获取hash集合中的所有key值
hvals key #获取hash集合中所有的value值
----------------------------------------------------------------
hincrby key name 1 #name的value加1操作
本机redis:0>hincrby myhash age 1
"25"
hsetnx key name value #不存在可以设置,存在的话不可以设置。
-----------------------------------------------------------------
hash更适合存对象,容易变更的对象。
5、zset(有序集合)
在set集合上添加了一个标量
zadd key int value #添加数据,int为标量
zcard key #判断集合长度
zrem key value #删除集合中某个元素
本机redis:0>zadd myset 1 name5
"1"
----------------------------------------------------
zrange key 0 -1 #查询所有的数据,并且自动的根据标量排序返回结果,从小到大。
zrevrange key 0 -1 #从大到小
zrangebyscore key -inf +inf withscores #标量可以是成绩,通过成绩排序并打印成绩
zrevrangebyscore key +inf -inf #从高到低
zcount key min max #获取标量在min-max区间内元素的个数。
本机redis:0>zcount myset 4000 5000
"2"
强大的排序,可以让一些东西带有权重,我们的排行榜,成绩了,工资了,最热信息等。
特殊数据类型
(1)geospatial (地理位置)
通过geospatial的命令我们可以保存地理位置,并在需要的时候检索出来。经纬度查询
- 有效经度为-180至180度。
- 有效纬度为-85.05112878至85.05112878度。
geoadd key a b name #a,b,name分别为纬度,经度,名称。
------------------------------------------------------
虚拟机:0>geoadd china 112.54 32.99 nanyang #添加南阳地理位置
"1"
虚拟机:0>geoadd china 114.08 22.54 shenzhen #添加深圳地理位置
"1"
-------------------------------------------------------
getdist china nanyang shenzhen #得到两所城市的直线距离,单位m
getdist china nanyang shenzhen km #单位km
虚拟机:0>geodist china nanyang shenzhen
"1172105.6693"
-------------------------------------------------------
geopos china nanyang #得到城市的经纬度
------------------------------------------------------
georadius china 110 30 1000 km #以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
georadius china 110 30 1000 km withdist #并返回距离中心点的距离
虚拟机:0>georadius china 110 30 1000 km withdist
"shenzhen"
"923.9364"
"nanyang"
"410.6106"
(2) hyperloglog(概率数据结构)
相当于我们数学中的基数,给一个集合返回不重复元素的数量。 有一组算法会以内存换取精度:您最终会得到带有标准误差的估计量,在Redis实施中,该误差小于1% , 该算法的神奇之处在于,您不再需要使用与所计数项目数量成正比的内存量,而是可以使用恒定数量的内存!在最坏的情况下为12k字节 ,可用于网站的(不重复)访问人数。
虚拟机:0>pfadd hll a b c d a #添加数据
"1"
虚拟机:0>pfcount hll #返回不重复结果的数量
"4"
pfmerge key3 key1 key2 #合并key1和key2到key3不重复
如果允许容错,那么一定可以使用Hyperloglog !
如果不允许容错,就使用set或者自己的数据类型即可!
(3)Bitmaps(位存储)
对于可以用0和1表达的事情,我们可以用Bitmaps,例如:系统的活跃人数,疫情的感染人数。所有人我们可以用0代替,感染的话就是1,这样就可以统计出来被感染的人数。两个状态的都可以这样用。操作二进制位操作。
#模拟人员一周的打卡 1代表打卡 0没有打卡
----------------------------------------------
虚拟机:0>setbit xiaoming 1 0 #模拟星期1
"1"
...
虚拟机:0>setbit xiaoming 5 1 #星期5
"0"
虚拟机:0>setbit xiaoming 6 1 #星期6
"0"
虚拟机:0>setbit xiaoming 7 1 #星期日
"0"
------------------------------------------
getbit xiaoming 6 #查看星期6的打卡情况
bitcount xiaoming #判断一周打卡天数
虚拟机:0>bitcount xiaoming
"6" #一周6天打卡