为什么要使用缓存?
因为每次查询数据库(Mysql、oracle)都会比较费时间,如果建立一个缓存数据库那么查询就会很快(就比如操作系统中,把经常访问的东西放入缓存中,访问起来就非常快)
1、内存存储、持久化
2、效率高、用于高速缓存
3、发布订阅系统
4、地图信息分析
5、计时器、计数器(浏览量)
key 命令: key * 表示查看所有的key exists 名称 :查看这个名称是否存在 move 名称 1 :移除一个数据类型 expire name 10:设置过期时间,10表示十秒钟后就自动过期 . ttl name :查看剩余时间 type name :查看name的类型
FLUSHDB:删除所有key,也就是清空数据库中的key
应用场景:统计数量、计数器、粉丝数、关注数…
可以存储比如jpg图片或者序列化的对象。string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
set name hui //设置值 get name //获得值 append name "hello" //追加一个"hello"到name后面,如果key不存在 就相当于set了一个key strlen name //返回name的长度 set age 20 incr age //对age实行+1操作 21 decr age //对age实行-1操作 20 incrby age 10 //对age实行+10的操作 decrby age 10 //对age实行-10的操作 ======================================== 字符串范围截取或替换:range set name "abcdefg" //设置key value getrange name 0 2 //截取字符串name中的[0,2]的值 abc setrange name 2 xxx //替换从下标为2开始的三个字符为xxx 值为:abxxxfg =========================================== # setex(set with expire) //设置过期时间 # setnx(set if not exist) //不存在设置(在分布式锁中比较常用) setex mykey 30 "hello,world!" //设置mykey的值且30秒后过期 setnx mykey "hello,student" //如果mykey不存在,就创建mykey 或者 存在的话,就创建失败 ============================================ # 批量设置和获取 mset和mget mset k1 v1 k2 v2 k3 v3 //设置多个key value mget k1 k2 k3 //获取多个key msetnx k1 v1 k4 v4 //因为k1存在所以设置不会成功,k4即使不存在也无法被创建(原子性操作:要么全成功,要么全失败) #可以将set构建成对象方式: set user:{id}:{fields} //这种方式可以设置可以达到(对象:字段:值) mset user:1:name 张三 user:1:age 20 mget user:1:name user:1:age //结果为:"张三" \n "20" ============================================== getset #先进行get再set 列子: getset database "mysql" //如果没有database这个key,就会先返回一个空(nil,然后会set值到这个key getset database "oracle" //结果为"mysql",显示之后又会马上再设置database的值为"oracle"
应用场景:粉丝列表、点赞人员、关注列表、(可以做简单的消息队列处理)
# List类型的命令都是l开头去书写的(LPUSH、LINDEX、LLEN、LPOP....) # 可以实现队列(LPUSH、RPUSH)、栈(只使用一种插入方式和弹出方式 -> 就能实现栈的操作) ============================================== LPUSH KEY VALUE [VALUE....] # 向List的key中插入value值(头部插入) RPUSH key value [value....] # 尾部插入 ============================================== LPOP KEY #在List列表的key中弹出左边一个值 RPOP KEY #在List列表中key弹出右边的值 ============================================== LRANGE key 0 1 # 获取key中0到1的值 LRANGE key 0 -1 # 获取key中所有的值 ============================================== LINDEX key 下标值 # 获取下标的值 ============================================== LLEN key # 查看key的长度 ============================================== LREM key count value # 移除指定的值 # example: 127.0.0.1:6379> lpush k1 v1 v1 v1 # 插入三个数(List 中允许重复值) 127.0.0.1:6379> LRANGE k1 0 -1 # 获取key中所有的值 1) "v1" 2) "v1" 3) "v1" 127.0.0.1:6379> LPUSH k1 v2 v3 # 再次往k1 中插入两个数 (integer) 5 127.0.0.1:6379> LRANGE k1 0 -1 # 获取key中所有的值 1) "v3" 2) "v2" 3) "v1" 4) "v1" 5) "v1" 127.0.0.1:6379> LREM k1 3 v1 # 移除k1中三个一样的值v1 (integer) 3 127.0.0.1:6379> LRANGE k1 0 -1 # 查看 1) "v3" 2) "v2" 127.0.0.1:6379> LREM k1 1 v2 # 移除k1 中1个v2 (integer) 1 127.0.0.1:6379> LRANGE k1 0 -1 # 查看 1) "v3"
127.0.0.1:6379> lpush kk k1 k2 k3 # 将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个 (integer) 3 # 空列表。 如果 key 对应的值不是一个 list 的话,那么会返回一个错误。 127.0.0.1:6379> lrange kk 0 -1 # 返回列表指定区间内的元素。 1) "k3" 2) "k2" 3) "k1" 127.0.0.1:6379> lpop kk # 从左边弹出一个元素 "k3" 127.0.0.1:6379> rpop kk # 从右边弹出一个元素 "k1" 127.0.0.1:6379> lrange kk 0 -1 1) "k2" 127.0.0.1:6379> lpush kk k3 k4 (integer) 3 127.0.0.1:6379> lrange kk 0 -1 1) "k4" 2) "k3" 3) "k2" 127.0.0.1:6379> LINDEX kk 2 # 获取到对应下标2 的值 "k2" 127.0.0.1:6379> BLPOP kk 3 # 阻塞弹出,对kk中弹出一个元素进行设置时间自动弹出(左弹出) 1) "kk" 2) "k4" 127.0.0.1:6379> LRANGE kk 0 -1 1) "k3" 2) "k2"
应用场景: 实现点赞,签到,like、实现关注模型,可能认识的人 等功能
# set存储是无序存储~ 127.0.0.1:6379> sadd hh h1 h2 h3 h4 # 添加元素到key中 (integer) 4 127.0.0.1:6379> SMEMBERS hh # 查看key下的所有元素 1) "h3" 2) "h4" 3) "h2" 4) "h1" 127.0.0.1:6379> SPOP hh 4 # 弹出key下 四个元素 1) "h3" 2) "h1" 3) "h2" 4) "h4" 127.0.0.1:6379> SMEMBERS hh # 再次查看(无数据,因为添加四个又弹出四个) (empty list or set) ================================================== 127.0.0.1:6379> SCARD hh # 查看key的length长度 (integer) 3 127.0.0.1:6379> SRANDMEMBER hh 2 # 随机弹出两个元素 1) "h3" 2) "h1" ================================================== 127.0.0.1:6379> SMEMBERS hh # 查看元素 1) "h3" 2) "h2" 3) "h1" 127.0.0.1:6379> SPOP hh 2 # 弹出两个元素 1) "h3" 2) "h2" 127.0.0.1:6379> SMEMBERS hh 1) "h1"
**应用场景:zset天生是用来做排行榜的、好友列表, 去重, 历史记录等业务需求 **
# zset相对于set,zset是一个有序集合,而set是无序集合 127.0.0.1:6379> zadd curry 1 stephen # 添加元素 (integer) 1 127.0.0.1:6379> zadd curry 1 curry (integer) 1 127.0.0.1:6379> ZRANGE curry 0 -1 # 返回key 中所有元素 1) "curry" 2) "stephen" 127.0.0.1:6379> zadd curry 2 james # 增加元素 (integer) 1 127.0.0.1:6379> ZRANGE curry 0 -1 # 返回key 中所有元素(正序返回) 1) "curry" 2) "stephen" 3) "james" 127.0.0.1:6379> ZREVRANGE curry 0 -1 # 返回元素(倒序返回) 1) "james" 2) "stephen" 3) "curry" ================================================== 127.0.0.1:6379> ZCARD curry # 返回key中元素个数 (integer) 3 ================================================== 127.0.0.1:6379> zadd curry 1 stephen (integer) 1 127.0.0.1:6379> ZADD curry 2 curry (integer) 1 127.0.0.1:6379> ZADD curry 3 mengshen (integer) 1 127.0.0.1:6379> ZRANGE curry 0 -1 1) "stephen" 2) "curry" 3) "mengshen" 127.0.0.1:6379> EXPIRE curry 30 # 为key设置过期时间 (integer) 1 127.0.0.1:6379> ttl curry # 查看key的过期时间 (integer) 28 127.0.0.1:6379> ttl curry (integer) 21 127.0.0.1:6379> PERSIST curry # 取消curry的过期时间(即不会随着时间过期) (integer) 1 127.0.0.1:6379> ttl curry (integer) -1 127.0.0.1:6379> ZRANGE curry 0 -1 # 查看key中所有元素 1) "stephen" 2) "curry" 3) "mengshen" ==================================================
应用场景:缓存、登陆session等…
# Hash 存储是由 key : value 形式存储 127.0.0.1:6379> HMSET hash1 k1 v1 k2 v2 k3 v3 # 批量设置设置hash1键对应的字段:值 OK 127.0.0.1:6379> HGETALL hash1 # 获取hash1键下全部的的key value 形式的值 1) "k1" 2) "v1" 3) "k2" 4) "v2" 5) "k3" 6) "v3" 127.0.0.1:6379> HSET hash1 k4 v5 # 设置单独的hash元素 (integer) 1 127.0.0.1:6379> HGETALL hash1 # 获取全部元素值 1) "k1" 2) "v1" 3) "k2" 4) "v2" 5) "k3" 6) "v3" 7) "k4" 8) "v5" 127.0.0.1:6379> HMGET hash1 k1 k2 k3 k4 k5 # 获取对应所在key下的 field字段的value (k5键不存在就返回nil) 1) "v1" 2) "v2" 3) "v3" 4) "v5" 5) (nil) ================================================== 127.0.0.1:6379> hset htest k1 v1 # 设置一个值 (integer) 1 127.0.0.1:6379> HSETNX htest k1 v2 # 想要修改k1的value 可是使用了HSETNX无法修改(不会覆盖以前的值) (integer) 0 127.0.0.1:6379> HGETALL htest # 获取键中所有的键值对值 1) "k1" 2) "v1" 127.0.0.1:6379> HVALS htest # 获取所有的value 1) "v1" 127.0.0.1:6379> HKEYS htest # 获取所有的key 1) "k1" 127.0.0.1:6379> HEXISTS htest k1 # 判断fields 是否存在 (integer) 1 ================================================== 127.0.0.1:6379> hset test plus 1 (integer) 1 127.0.0.1:6379> HGETALL test 1) "plus" 2) "1" 127.0.0.1:6379> HINCRBY test plus 2 # 对plus进行自增 (integer) 3 127.0.0.1:6379> hget test plus # 获取自增后的值 "3" 127.0.0.1:6379> HINCRBY test plus 77 # 对plus的value进行自增77 (integer) 80 127.0.0.1:6379> HGETALL test # 获取key(test)的value 1) "plus" 2) "80" 127.0.0.1:6379> HINCRBYFLOAT test plus 2 # 浮点数自增 "82"(浮点数float) 127.0.0.1:6379> hlen test # 返回test这个key的长度 (integer) 1 127.0.0.1:6379> hstrlen test plus # 返回key对应value 的长度 (integer)
geospatial => 应用场景:地理位置、附近的人、导航…
# example: # GEOADD / GEOPOS 用法 # 格式: GEOADD key(键值) longitude(经度) latitude(纬度) member(名称) [longitude latitude member ...] 127.0.0.1:6379> GEOADD china:city 106.5 29.4 chongqing # 添加重庆位置详情 (integer) 1 127.0.0.1:6379> GEOPOS china:city chongqing # 查看重庆地理位置 1) "106.49999767541885" 2) "29.399998800186417" #################################################### # GEOADD / GEODIST 用法 计算两个人或城市的距离 127.0.0.1:6379> GEOADD instance 106.5 29.4 chongqing 104.1 30.6 chengdu # 添加两个城市 (integer) 2 127.0.0.1:6379> GEODIST instance chongqing chengdu # 计算两个城市的距离(m) "266931.9728" 127.0.0.1:6379> GEODIST instance chongqing chengdu km # 计算两个城市的距离(km) "266.9320" #################################################### GEORADIUS: GEORADIUS china:city longitude latitude radius m|km|ft|mi # (以经纬度为中心寻找radius为半径的所有距离在内的城市或人) 127.0.0.1:6379> GEORADIUS china:city 105 28 500 km # 以(105, 28)为中心 寻找出半径500为中心的500km的城市 1) "chongqing"
bitmap应用场景:存储用户是否在线状态…
bit: 会让我们联想到的就是二进制,但是底层还是应用的是对字符串的操作!
参考博客redis三种特殊类型
# bitmap 主要命令 setbit getbit bitcount ########################################################## setbit key offset value # 设置一个key(可以是字段) offset如果长度超过字符串长度,会默认用0进行填充, value表示状态默认为0(只能为1或0) # example setbit test 2 1 # 设置test默认长度为2且值为1 gitbit test 1 # 获取test状态值, 1表示value ########################################################## 127.0.0.1:6379> setbit ahui 2 1 # 设置值 (integer) 0 127.0.0.1:6379> setbit ahui 5 1 (integer) 0 127.0.0.1:6379> GETBIT ahui 2 # 获取offset为2的个数 (integer) 1 127.0.0.1:6379> BITCOUNT ahui # 统计key中元素个数 (integer) 2
应用场景:统计不重复的元素计数(省内存)
统计数据很快,但是无法查看统计元素内容!!!!
# 主要命令 pfadd key value [value....] # 存入元素 pfcount key # 返回key中所有元素 pfadd key1 value [value ...] # 再次存入 pfmerge key2 key1 key # 创建key2 把key1 key的值进行合并 pfcount key2 # 统计key2集合中的个数 ########################################################## 127.0.0.1:6379> PFADD key a b c d e # 添加元素 (integer) 1 127.0.0.1:6379> pfcount key # 统计元素 (integer) 5 127.0.0.1:6379> pfadd key1 1 2 3 4 5 (integer) 1 127.0.0.1:6379> pfcount key1 (integer) 5 127.0.0.1:6379> PFMERGE key2 key key1 # 合并两个key的数值 OK 127.0.0.1:6379> pfcount key2 # 查看合并后的数量 (integer) 10
y1 key的值进行合并
pfcount key2 # 统计key2集合中的个数
##########################################################
127.0.0.1:6379> PFADD key a b c d e # 添加元素
(integer) 1
127.0.0.1:6379> pfcount key # 统计元素
(integer) 5
127.0.0.1:6379> pfadd key1 1 2 3 4 5
(integer) 1
127.0.0.1:6379> pfcount key1
(integer) 5
127.0.0.1:6379> PFMERGE key2 key key1 # 合并两个key的数值
OK
127.0.0.1:6379> pfcount key2 # 查看合并后的数量
(integer) 10