Redis用来做什么?
Redis一般用于缓存,在一个网页里,有些数据经常被查询;比如说某小说网站当日热读榜,用户访问该网站就会自动查询显示,如果每次都数据库(MySQL,Oracle)中查询会浪费资源,因为在数据库的查询操作比较耗时间。而在缓存中的查询操作则比数据库的查询操作更快,因此可以将这些数据放入缓存中来提高性能。Redis也可用于分布式锁。
关于Redis端口的趣事
Redis的默认端口是6379,用手机9位键盘的MREZ的位置决定,这是Redis作者Antirez朋友圈愚蠢的代名词,原语意大利广告女郎在电视节目说的一堆愚蠢的话,还真有趣。
Redis的基础数据结构
Redis的基础数据结构有string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合)。
string(字符)
结构
字符串string是以key,value形式来存储数据,通过唯一的key来的到value。
字符串string是一个动态字符串,可修改,长度可变;底层结构实现类似Java的ArrayList,当长度不够是加倍现有空间,当长度超过1M时,每次增加1M。字符串最大长度512M。
基本指令
>set name Jay
ok
>get name
Jay
>exists name
(integer) 1
>del name
(integer) 1
>get name
(nil)
批量操作
>mset name1 book1 百年孤独 book2 刻意练习
>meget book1 book2
"百年孤独"
"刻意练习"
设置过期时间
>set name dio
>get name
"dio"
>expire name 5 #5s后过期
#wait for 5s
>get name
(nil)
>setex name 10 Redis #10s后过期
#wait for 10s
>get name
(nil)
>setnx name Java
>get name
"Java"
>setnx name C++
>get name
"java" #因为name已经存在,所以setnx name C++无效
list(列表)
底层结构
Redis的列表类似于Java中的LinkedList,这意味着插入和删除操作非常快,时间复杂度为O(1),查询操作非常慢,时间复杂度为O(n)。
实际上列表list的存储结构是quicklist,当数据量较少时数据存在ziplist中,数据量较多时转换为quicklist。普通的链表附加的索引指针消耗的空间太大,导致内存中出现许多内存碎片,浪费内存空间;而ziplist是将数据存储在一块紧挨着的内存空间。quicklist是链表和ziplist的结合,将大量的数据分为若干块,每一块存在ziplist中,然后将ziplist以链表的方式连接。
list可以实现队列和栈
队列(右进左出):
>rpush students james jack jhon
(integer) 3
>llen students
(integer) 3
>lpop students
james
>lpop students
jack
>lpop students
jhon
>lpop students
(nil)
栈(右进右出):
>rpush students james jack jhon
(integer) 3
>llen students
(integer) 3
>rpop students
jhon
>rpop students
jack
>rpop students
james
>lpop students
(nil)
其他操作:
>rpush students james jack jhon
lrange students 0 -1 #O(n)慎用
"james"
"jack"
"jhon"
>lindex 1 #O(n)慎用
"jack"
hash(哈希)
结构
Redis中的hash类似于Java中的HashMap,hash的存储结构是数组+链表,与jdk1.8之前的一样。
Redis的hash的value只能存字符串。
Redis为了高性能,不能阻塞服务,采用渐进式的rehash策略,渐进式的rehash策略在rehash的时保留新旧两个hash结构 ,查询时查询两个hash结构,在后续的定时任务和hash子操作中会将旧的hash内容一步步拷贝到新的hash结构中。
hash中的最后一个元素被删除时,hash的结构也会被删除。
hash存储信息时可以进行部分存储和获取,比如学生信息有姓名,年龄,性别,身高,体重。这五个字段可以单独存储和获取,而不需要一次性全部存储(序列化)和获取(有时不需要获取学生全部信息)。hash的存储结构消耗高于string。
基本指令
hset ss james "I love Redis"
>(integer) 1
hset ss jack "I love Java"
>(integer) 1
>hset ss Java "jack love me"
(integer) 1
>hlen ss
(integer) 3
>hgetall ss
"james"
"I love Redis"
"jack"
"I love Java"
"Java"
hmset ss james "I love Redis jack "I love Java Java "jack love me"
set(集合)
结构
set是一个键值对无序不可重复的集合,相当于Java中的HashSet。当移除完最后一个元素时,其数据结构自动删除,内存也被回收。
基本指令
>sadd students jackson
(integer) 1
>sadd students jackson
(integer) 0 #重复了
>sadd students Rose 阿鱼
(integer) 1
>smembers students
"jackson"
"阿鱼"
"Rose"
>scard students #统计个数
(integer) 3
>spop students #弹出一个幸运儿
"阿鱼"
zset(有序集合)
结构
zset的value值唯一且有序,每一个value有一个与之对应的score,score作为value[的排序权重内部通过一个名为跳跃列表的数据结构实现(个人感觉跳跃列表有点类似于一棵树)。
基本指令
>zadd stus 9.9 "Rose"
(integer) 1
>zadd stus 8.9 "Jhon"
(integer) 1
>zadd stus 9.6 "Blue"
(integer) 1
>zrange stus 0 -1 #顺序输出
"Jhon"
"Blue"
"Rose"
>zrevrange stus 0 -1#逆序输出
"Rose"
"Blue"
"Jhon"
>zcard stus #统计个数