Redis入门
1.Redis安装:
1).官网下载Redis安装包
2).将安装包传到Linux系统
3).将安装包拷贝到 /opt
4).解压并进入解压后目录
5).执行make,再执行make install
6).切换到/usr/local/bin目录下

7).拷贝Redis的配置文件(redis.conf)到当前目录下
8).修改配置文件

9).启动Redis的服务器 执行命令 ./redis-server redis.conf
10).启动Redis的客户端 执行命令 ./redis-cli -p 6379
11).测试是否连接上Redis的服务器 执行命令 ping

至此,Redis已经安装完毕并可以使用。
2.Redis的基本概念
Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
3.Redis基本操作
Redis默认有16个数据库,默认使用的是第0个数据库,可以通过select切换数据库。
Redis对于大小写不区分。
1).select
作用:切换数据库
格式:select index

2).dasize
作用:查看数据大小
格式:dbsize

3).keys
作用:查看所有key
格式:keys *
127.0.0.1:6379[3]> KEYS * #查看所有的key
1) "name"
2) "age"
4).flushdb flushall
作用:
flushdb :清空当前数据库
flushall:清空所有数据库
127.0.0.1:6379[3]> FLUSHDB #清空当前数据库
OK
127.0.0.1:6379[3]> KEYS *
(empty array)
127.0.0.1:6379[3]> FLUSHALL #清空所有的数据库
OK
4.Redis是单线程的
Redis是很快的,官方表示,Redis是基于内存操作的,CPU不是Redis的性能瓶颈,Redis的瓶颈就是根据机器的内存和网络带宽。既然可以使用单线程来实现,就使用单线程了!
Redis是C语言实现的,官方数据:读:110000/s 写: 80000/s,完全不比同样使用key-value的Memcached差
1).Redis为什么单线程还这么快?
错误1: 高性能的服务器一定是多线程的
错误2: 多线程(CPU上下文切换)一定比单线程效率高
核心: Redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,相比多线程,减少了CPU上下文切换的耗时。对于内存系统来说,没有上下文切换效率就是最高的,多次读写都是在一个CPU上的。
5.Redis的五种基本类型
1).Redis-key
# SET 设置key
# GET 查看key的值
# EXPIRE 设置key的过期时间
# TTL 查看key剩余的时间
# EXISTS 判断当前的key是否存在
# KEYS * 查看当前所有的key
# DEL key 删除当前的key
# TYPE 查看key存储的value的类型
2).string字符串
set和get
作用:设置值以及获取值
格式: set key value
get key
127.0.0.1:6379> set key1 v1 #设置值
OK
127.0.0.1:6379> get key1 #获得值
"v1"
exists
作用:判断key是否存在
格式:exists key
127.0.0.1:6379> EXISTS key1 #判断key是否存在
(integer) 1
append
作用:追加字符串,if key不存在,相当于set命令
格式:append key value
127.0.0.1:6379> APPEND key1 hello #追加字符串,如果当前key不存在,相当于set命名
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
strlen
作用:获取字符串长度
格式:strlen key
127.0.0.1:6379> STRLEN key1 #获得字符串的长度 (integer) 7
127.0.0.1:6379> append key1 wang
(integer) 11
127.0.0.1:6379> strlen key1
(integer) 11
127.0.0.1:6379> get key1
"v1hellowang"
incr和 decr
作用:对value进行自增1和自减1操作
格式: incr key decr key
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> INCR views # i++操作
(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 # i--操作
(integer) 1
127.0.0.1:6379> get views
"1"
127.0.0.1:6379> DECR views
(integer) 0
127.0.0.1:6379> get views
"0"
incrby 和decrby
作用:设置加减的步长
用法: incrby key num decrby key num
127.0.0.1:6379> INCRBY views 10 # 设置自增的步长 (integer) 10
127.0.0.1:6379> INCRBY views 10
(integer) 20
127.0.0.1:6379> get views
"20"
127.0.0.1:6379> DECRBY views 5 # 设置自减的步长 (integer) 15
127.0.0.1:6379> DECRBY views 5
(integer) 10
127.0.0.1:6379> get views
"10"
getrange
作用:获取给定范围字符串值
格式:getrange key start stop
127.0.0.1:6379> set key1 hello,wang
OK
127.0.0.1:6379> get key1
"hello,wang"
127.0.0.1:6379> GETRANGE key1 0 3 # 查看给定范围的字符串
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1 #类似于get命令,查看所有的字符串
"hello,wang"
setrange
作用:从指定位置开始替换字符串的值
格式:setrange key offset value
127.0.0.1:6379> GETRANGE key1 0 -1
"hello,wang"
127.0.0.1:6379> SETRANGE key1 2 xxx # 替换指定位置开始的字符串
(integer) 10
127.0.0.1:6379> GETRANGE key1 0 -1
"hexxx,wang"
setex 和ttl
作用:设置过期时间,查看剩余时间
格式:setex key seconds value ttl key
127.0.0.1:6379> setex key2 30 v2
OK
127.0.0.1:6379> TTL key2
(integer) 21
127.0.0.1:6379> TTL key2
(integer) 20
127.0.0.1:6379> TTL key2
(integer) 18
setnx
作用:如果key不存在则设置,否则失败
格式:setnx key value
#setnx 如果当前值不存在,则设置 (在分布式锁中经常使用) 127.0.0.1:6379> setnx mykey redis #如果值不存在,则创建成功
OK
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379> setnx mykey mongodb #如果值存在,则创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
mset和 mget
作用:同时设置或者获取多个值
格式:mset key1 value1 key2 value2 ... mget key1 key2...
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> mset key1 v1 key2 v2 key3 v3 #同时设置多个值
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key2"
3) "key1"
127.0.0.1:6379> mget key1 key2 key3 #同时获取多个值
1) "v1"
2) "v2"
3) "v3"
msetnx
作用:msetnx是一个原子操作,要么一起成功,要么一起失败
127.0.0.1:6379> msetnx key1 v1 key4 v4 #msetnx是一个原子操作,要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get key4
(nil)
用string存储对象时key值的设计
#对象
set user:1 {name:zhangsan, age:20} #设置一个user:1对象 值为Json字符串
#这里的key是一个巧妙的设计: user:{id}:{filed} 127.0.0.1:6379> mset user:1:name zhangsan user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "20"
getset
作用:先获取值再设置值
格式:getset key value
#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除了是字符串也可以是数字!
(1) 计数器
(2)统计多单位的数量
(3)对象缓存存储
3)列表 list
所有的list命令都是用l开头的
lpush rpush
作用:从list的左边或者右边插入值
格式: lpush key value rpush key value
lrange
作用:获取指定范围的值
格式: lrange key start stop
127.0.0.1:6379> LPUSH list one # 将一个值或者多个值,插入到列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1 # 获取list中的值
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1 # 通过区间获取具体的值
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list right # 将一个值或者多个值,插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
lpop rpop
作用:从列表的左边或者右边移除值
格式: lpop key rpop key
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "right"
127.0.0.1:6379> LPOP list #移除list的第一个元素
"three"
127.0.0.1:6379> RPOP list #移除list的最后一个元素
"right"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
lindex
作用:获取指定下标的值
格式:lindex key index
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> LINDEX list 0 #通过下标获取一个值
"two"
127.0.0.1:6379> LINDEX list 1
"one"
llen
作用:获取列表中元素个数
格式:llen key
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> LLEN list # 获取list的长度
(integer) 2
lrem
作用:移除列表中元素
格式:lrem key count value
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> LREM list 1 one #移除list中的1个one
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
ltrim
作用:截取列表的值
格式:ltrim key start stop
127.0.0.1:6379> LPUSH list hello hello1 hello2 hello3
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
4) "hello"
127.0.0.1:6379> LTRIM list 1 2 # 通过下标截取指定的长度,这个list已经改变了,截断了只剩下截取的 元素!
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "hello2"
2) "hello1"
rpoplpush
作用:移除列表中最后一个元素,将它添加到另一个列表中
格式:rpoplpush key1 key2
127.0.0.1:6379> LRANGE list 0 -1
1) "hello2"
2) "hello1"
127.0.0.1:6379> RPOPLPUSH list list2 # 移除列表的最后一个元素,将它移动到新的列表中
"hello1"
127.0.0.1:6379> LRANGE list 0 -1 # 查看原来的列表
1) "hello2"
127.0.0.1:6379> LRANGE list2 0 -1 # 查看目标列表,确实存在该值 1)
"hello1"
lset
作用:根据下标替换列表中的值
格式:lset key index value
#LSET 将列表中指定下标的值替换为另外一个值,相当于更新操作
127.0.0.1:6379> LRANGE list 0 -1
1) "hello2"
127.0.0.1:6379> LSET list 0 world # 将0号下标的值替换为world
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "world"
127.0.0.1:6379> LSET list 1 other # 修改不存在的下标,报错
(error) ERR index out of range
linsert
作用:在列表中插入值
格式:linsert key before|after value new_value
# LINSERT 将某个具体的value插入到列表中某个值的前面或后面
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> LINSERT list before world other
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> LINSERT list after world "new"
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"
小结:
他实际上是一个链表,before or after, left,right都可以插入值
如果key不存在,创建新的链表
如果key存在,新增内容 如果移除了所有的值,空链表,也代表不存在
在两遍插入或者改动值,效率最高!中间元素,相对来说效率会低一点
队列: LPOP RPUSH
栈: LPOP LPUSH
4)集合set
set中的值是不可以重复的
sadd
作用:给set中添加值
格式:sadd key value1 value2 ...
127.0.0.1:6379> sadd myset hello #set集合中添加值
(integer) 1
127.0.0.1:6379> sadd myset world
(integer) 1
127.0.0.1:6379> sadd myset wang
(integer) 1
127.0.0.1:6379> sadd myset hello #设置重复值时,失败
(integer) 0
smembers
作用:获取set中的所有值
格式:smembers key
127.0.0.1:6379> SMEMBERS myset #获取set的所有值
1) "hello"
2) "world"
3) "wang"
sismember
作用:判断某个值是否在set中
格式:sismember key value
127.0.0.1:6379> SISMEMBER myset hello #判断某个值是否在set集合中
(integer) 1
127.0.0.1:6379> SISMEMBER myset he
(integer) 0
scard
作用:获取set中元素的个数
格式:scard key
127.0.0.1:6379> scard myset #获取set集合中的元素个数
(integer) 3
screm
作用:删除set中的值
格式:srem key value1 value2....
127.0.0.1:6379> SREM myset hello #删除set集中的元素
(integer) 1
127.0.0.1:6379> SREM myset he #删除set集合中不存在的元素,则失败
(integer) 0
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "wang"
srandmember
作用:从set中获取随机值
格式:srandmember key count
#set是无序不重复的,可以获取随机值
127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "world"
3) "chen"
4) "wang"
127.0.0.1:6379> SRANDMEMBER myset # 从set集合中获取一个随机值
"chen"
127.0.0.1:6379> SRANDMEMBER myset # 从set集合中获取一个随机值
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"world"
127.0.0.1:6379> SRANDMEMBER myset
"wang"
127.0.0.1:6379> SRANDMEMBER myset
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"chen"
127.0.0.1:6379> SRANDMEMBER myset 2 #从set集合中获取指定个数的随机值
1) "wang"
2) "chen"
spop
作用:随机删除指定个数个元素
格式:spop key count
127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "world"
3) "chen"
4) "wang"
127.0.0.1:6379> spop myset #随机删除指定个数的元素
"chen"
127.0.0.1:6379> spop myset
"hello"
smove
作用:将指定的元素从一个set中移动到另一个set中
格式:smove set1 set2 value
127.0.0.1:6379> sadd myset hello world wang
(integer) 3
127.0.0.1:6379> sadd myset2 set2
(integer) 1 127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "world"
3) "wang"
127.0.0.1:6379> SMEMBERS myset2
1) "set2"
127.0.0.1:6379> smove myset myset2 hello #从一个集合中移动一个值到另一个集合中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "wang"
127.0.0.1:6379> SMEMBERS myset2
1) "hello"
2) "set2"
数字类集合:
(1)差集
(2)交集
(3)并集
应用:
抖音中,A用户将所有关注的人放在一个set集合中,将他的粉丝放在一个集合中可以实现共同关注,共同爱好,二度好友(推荐好友)等
127.0.0.1:6379> sadd set1 a b c
(integer) 3
127.0.0.1:6379> sadd set2 c d e
(integer) 3
127.0.0.1:6379> SMEMBERS set1
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> SMEMBERS set2
1) "d"
2) "e"
3) "c"
127.0.0.1:6379> sdiff set1 set2 # 差集
1) "a"
2) "b"
127.0.0.1:6379> SINTER set1 set2 # 交集 共同还有可以通过这个实现
1) "c"
127.0.0.1:6379> SUNION set1 set2 # 并集
1) "a"
2) "b"
3) "c"
4) "e"
5) "d"
5)哈希hash
可以将哈希看成是一个Map集合,key-value中的value是一个map集合
hset hget
作用:设置或者获取一个hash的值
格式:hset key field1 value1 hget key field
127.0.0.1:6379> hset myhash field1 wang #设置一个hash的值
(integer) 1
127.0.0.1:6379> hget myhash field1 #获取一个hash的值
"wang"
hmset hmget
作用:设置或者获取一个hash值
格式:
hmset key field1 value1 field2 value2 ...
hmget key field1 field2...
127.0.0.1:6379> hmset myhash field2 mal field3 hello #同时设置多个hash的值
OK
127.0.0.1:6379> hmget myhash field1 field2 field3 #同时获取多个hash值
1) "wang"
2) "mal"
3) "hello"
getall
作用:获取hash中所有值
127.0.0.1:6379> hgetall myhash #获取hash中的所有的值 1) "field1"
2) "wang"
3) "field2"
4) "mal"
5) "field3"
6) "hello"
hdel
作用:删除指定field的hash键值对
格式:hdel key field
127.0.0.1:6379> hdel myhash field2 #删除指定的hash值,对应的value值也就删除了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "wang"
3) "field3"
4) "hello"
hlen
作用:获取hash的键值对个数
格式:hlen key
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "wang"
3) "field3"
4) "hello"
127.0.0.1:6379> hlen myhash #获取hash的键值对的个数 (integer) 2
hexists
作用:判断hash中的字段是否存在
格式:hexists key field
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "wang"
3) "field3"
4) "hello"
127.0.0.1:6379> HEXISTS myhash field1 #判断hash中指定的字段是否存在
(integer) 1
127.0.0.1:6379> HEXISTS myhash field2
(integer) 0
127.0.0.1:6379> HEXISTS myhash field3
(integer) 1
hkeys hvals
作用:获取hash中所有的字段或者值
格式:hkeys key hvals
127.0.0.1:6379> hkeys myhash #获取hash中所有的字段 1) "field1"
2) "field3"
127.0.0.1:6379> hvals myhash #获取hash中所有的值
1) "wang"
2) "hello"
hincrby
作用:给hash中指定字段的值加上一个增量
127.0.0.1:6379> hset myhash field4 5
(integer) 1
127.0.0.1:6379> HINCRBY myhash field4 2 #给hash的值一个增量
(integer) 7
127.0.0.1:6379> HINCRBY myhash field4 -1 #给hash的值一个减量
(integer) 6
hsetnx
作用:如果不存在,则添加,如果存在,则失败
格式:hsetnx key field value
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field3"
3) "field4"
127.0.0.1:6379> hsetnx myhash field5 zhang #如果不存在,则添加
(integer) 1
127.0.0.1:6379> hsetnx myhash field5 yang #如果存在,则不能添加
(integer) 0
hash的应用
hash中存储经常变更的值:比如用户信息: user :name-value,age-value,sex-value
hash更适合对象的存储,String更加适合字符串存储
6)有序集合 zset
zadd
作用:添加一个值
格式:zadd key scores value
127.0.0.1:6379> zadd myset 1 wang #添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 yang 3 zhang #添加多个值
(integer) 2
zrange
作用:获取zset中一个范围的值
格式:zrange key start stop
127.0.0.1:6379> ZRANGE myset 0 -1 #获取zset中的所有元素
1) "wang"
2) "yang"
3) "zhang"
zrangebyscore
作用:将zset中的值按照score从小到大排序输出
格式:zrangebyscore key min max
127.0.0.1:6379> ZRANGEBYSCORE myset -inf +inf #按照从小到大排序
1) "wang"
2) "yang"
3) "zhang"
127.0.0.1:6379> ZRANGEBYSCORE myset -inf +inf withscores #按照从下到大排序并显示scores
1) "wang"
2) "1"
3) "yang"
4) "2"
5) "zhang"
6) "3"
zrem
作用:移除zset中指定的元素
格式:zrem key value
127.0.0.1:6379> ZRANGE myset 0 -1
1) "wang"
2) "yang"
3) "zhang"
127.0.0.1:6379> zrem myset yang #移除zset中指定的元素
(integer) 1
127.0.0.1:6379> zrange myset 0 -1
1) "wang"
2) "zhang"
zcard
作用:查看zset中的元素个数
格式:zcard key
127.0.0.1:6379> ZRANGE myset 0 -1
1) "wang"
2) "yang"
3) "zhang"
127.0.0.1:6379> ZCARD myset #查看set中有几个元素
(integer) 3
zcount
作用:根据score的值统计在给定区间的元素个数
格式:zcount key min max
127.0.0.1:6379> zrange myset 0 -1
1) "yang"
2) "zhang"
3) "wang"
127.0.0.1:6379> zcount myset 1 3 #统计scores在1 到 3 区间内元素的个数
(integer) 3
127.0.0.1:6379> zcount myset 1 2 #统计scores在1 到 2 区间内元素的个数
(integer) 2


浙公网安备 33010602011771号