Redis(Remote Dictionary Server,远程字典服务)
概述
redis是什么?
是一个开源的使用ANSI C语言编写,支持网络、可基于内存、可持久化的日志型、key-value数据库,提供多种语言的API。
当下最热门的NOSQL技术之一,被称为结构化数据库。
redis会周期性的把更新数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis能干什么?
内存存储、持久化(内存是断电即失的,所以持久化很重要,rdb、aof)
效率高,可高速缓存
发布订阅系统
地图信息分析
计时器、计数器(浏览量!)
特性
多样的数据类型
持久化
集群
事务
Redis 基本说明
测试性能
使用redis-benchmark
简单操作
- 默认后台开启 :vim redis.conf(/usr/local/bin/kconfig),修改daemonize yes
- 开启redis服务(/usr/local/bin):redis-server kconfig/redis.conf
- 使用redis客户端:redis-cli
- set、get简单操作
- 默认16 (0)数据库:database 16(选择数据库用select index)
- DBSIZE:返回当前数据key数量
- keys *:查看所有key值
- exists key:判断key是否存在
- del name :移除key为name,当前数据库
- move name db:转移到指定数据库
- type name:查看类型
- expire name xx:设置name失效时间(cookie、单点登录、热点信息),单位是秒
- append key “hello”/hello:追加
- strlen key1:获取字符串长度
- flushdb:清空当前数据库
- flushall:清除所有数据库
为什么redis端口是6379:明星名字缩写
redis是单线程的!(6.0以前,6.0之后改为多线程)
redis是很快的,Redis是基于内存操作,CPU不是redis性能瓶颈,而是根据机器的内存和网络带宽。
单线程为什么也快?C语言写的,官方数据为 100 000+ 的QPS,完全不比key-value的Memecache差
五大数据类型
String
基本命令
set key value
get key
keys *
exists key
append key “追加字符串”:没有则相当于set key
strlen key
自增/自减
incr key:实现自增(浏览量)
decr key:自减
- incrby key 10 :步长增加10
- decrby key 10:步长减少10
字符串截取/替换:
- getrange key 0 3:获取key【0,3】
- setrange key2 1 xx:将第二个元素开始替换成xx
setex/setnx
-
setex(set with expire):设置过期时间
-
setnx(set if exist):不存在设置(分布式锁中常常存在),存在失败
区别与 set key value ,防止存在覆盖
mset/mget
msetnx :原子性操作
新建对象:
常规创建:
mset巧用:mset user:1:name user:1:age 13
getset:先get后set
String使用场景:除了是字符串还可以是数字
- 计数器
- 统计数量 uid:2131:follow 0 incr
- 粉丝数
- 对象存储缓存
list(列表)
#################################################################
在redis 中,可以把list玩成:栈、队列、阻塞队列
所有list命令都是 l 开头
#################################################################
- lpush list value
- rpush list value
- lrange list 0 -1
#################################################################
- lpop list:移除第一个元素
- rpop list:移除最后一个元素
#################################################################
- lindex 0 -1 :通过下标获得某个元素
#################################################################
- llen list:获取列表长度
#################################################################
- lrem list 1 like:移除列表指定个数value
#################################################################
- ltrim list 1 2:通过下标截取指定长度,list已经被改变,截断了只剩下截取的元素
#################################################################
- rpoplpush list otherlist :移除list最后一个元素添加到otherlist
#################################################################
- lset list 0 item:通过指定下标更新,存在更新,不存在报错
- lpush list value:存在list,就存入;不存在就新建再存入
#################################################################
- linsert key before|after pivot element:将某个value插入到某个元素前面或者后面
#################################################################
List 小结:
- 实际上是一个链表,before Node after,left ,right都可以插入
- 如果key不存在,创建新的链表
- 如果存在,新增内容
- 如果为空,也代表不存在
- 两边插入或者改动值,效率最高。中间元素,效率相对较低
消息队列:(左边进入,右边拿出来) lpush rpop
栈:(左边进去,左边那出来)lpush lpop
#################################################################
Set(集合):值不能重复
#################################################################
- sadd set value
- smembers set:查看所有元素
- sismember set fanzhe:判断set中是否存在value(1/0)
127.0.0.1:6379[2]> sadd set hello
(integer) 1
127.0.0.1:6379[2]> sadd set fanzhe
(integer) 1
127.0.0.1:6379[2]> sadd set zhaosiyuan
(integer) 1
127.0.0.1:6379[2]> smembers set
- “fanzhe”
- “hello”
- “zhaosiyuan”
127.0.0.1:6379[2]> sismember set fanzhe
(integer) 1
#################################################################
- scard set:获取set集合中的内容元素个数
127.0.0.1:6379[2]> scard set
(integer) 3
#################################################################
- srem set value:移除set集合中指定元素
127.0.0.1:6379[3]> srem set hello
(integer) 1
127.0.0.1:6379[3]> scard set
(integer) 2
127.0.0.1:6379[3]> smembers set
- “fanzhe”
- “zhaosiyuan”
#################################################################
set集合无序不重复。抽随机!
- srandmember set :随机一个
- srandmember set 2:随机指定个数
127.0.0.1:6379[3]> SRANDMEMBER set
“fanzhe”
127.0.0.1:6379[3]> SRANDMEMBER set
“zhaosiyuan”
127.0.0.1:6379[3]> SRANDMEMBER set
“fanzhe”
127.0.0.1:6379[3]> SRANDMEMBER set 2
- “fanzhe”
- “zhaosiyuan”
#################################################################
- spop set:删除指定key,随机删除key
127.0.0.1:6379[3]> spop set
“hello”
127.0.0.1:6379[3]> spop set
“zhaosiyuan”
127.0.0.1:6379[3]> smembers set
- “fanzhe”
- “hello2”
- “hello3”
- “hello1”
#################################################################
- smove source destination member: 将一个指定值一定到另外set集合中
127.0.0.1:6379[3]> smove set1 set2 hello
(integer) 1
127.0.0.1:6379[3]> smembers set2
- “fanzhe”
- “hello”
- “zhaosiyuan”
#################################################################
微博、B站,共同关注!(交集)
数字集合类:
- 差集 :sdiff
- 交集:sinter
- 并集:sunion
127.0.0.1:6379[3]> sadd k1 a
(integer) 1
127.0.0.1:6379[3]> sadd k1 b
(integer) 1
127.0.0.1:6379[3]> sadd k1 c
(integer) 1
127.0.0.1:6379[3]> sadd k2 c
(integer) 1
127.0.0.1:6379[3]> sadd k2 d
(integer) 1
127.0.0.1:6379[3]> sadd k2 e
(integer) 1
127.0.0.1:6379[3]> sdiff k1 k2 #差集
- “a”
- “b”
127.0.0.1:6379[3]> sinter k1 k2 # 交集 - “c”
127.0.0.1:6379[3]> sunion k1 k2 #并集 - “a”
- “b”
- “c”
- “e”
- “d”
微博:A用户将所有关注的人放在一个set集合中!将他的粉丝放入一个集合中!
共同关注,共同爱好,二度好友(六度分隔理论)
#################################################################
hash(哈希)
Map集合,key - value 值是一个map集合!本质和String类型没有太大区别,还是一个简单的key-value!
- hset hash k1 v:set一个键值对
- hget hash k1:通过k 得到v
- hmset hash k1 v1 k2 v2 :set多个键值对,重复的k会覆盖v
- hget hash k1 k2:通过多个k得到多个v
- hgetall hash :得到全部k v
- hdel hash key:删除哈希指定的key
127.0.0.1:6379[4]> hset hash field1 fanzhe #set一个具体的key-value
(integer) 1
127.0.0.1:6379[4]> hget hash field1 #获取一个字段值
“fanzhe”
127.0.0.1:6379[4]> hmset hash field1 hello field2 world #set多个
OK
127.0.0.1:6379[4]> hmget hash field1 field2#获取多个字段值
- “hello”
- “world”
127.0.0.1:6379[4]> hgetall hash #获取全部数据 - “field1”
- “hello”
- “field2”
- “world”
127.0.0.1:6379[4]> hdel hash field1 #删除哈希指定的key
(integer) 1
#################################################################
- hlen:获取hash表的字段数量
127.0.0.1:6379[4]> hlen hash
(integer) 1
#################################################################
- hexists hash key:判断hash指定字段是否存在
127.0.0.1:6379[4]> hexists hash field2
(integer) 1
127.0.0.1:6379[4]> hexists hash field
(integer) 0
#################################################################
- hkeys hash:获取所有key
- hvals hash:获取所有value
127.0.0.1:6379[4]> hkeys hash
- “field2”
127.0.0.1:6379[4]> hvals hash - “world”
#################################################################
- hincr hash key 1:设置增量
- decr:自减还是用hincr,设置为-1
- hsetnx hash key value:
127.0.0.1:6379[4]> hset hash field3 5 #指定增量
(integer) 1
127.0.0.1:6379[4]> hincrby hash field3 1
(integer) 6
127.0.0.1:6379[4]> hincrby hash field3 1
(integer) 7
127.0.0.1:6379[4]> hincrby hash field3 -2
(integer) 5
127.0.0.1:6379[4]> hsetnx myhash field4 hello #不存在可以设置
(integer) 1
127.0.0.1:6379[4]> hsetnx myhash field4 world #存在不能设置,防止覆盖
(integer) 0
#################################################################
hash变更的数据 user name age,尤其是用户信息之类的,经常变动的信息!hash更适合对象的存储,String更适合字符串存储
例:hash存储user 信息
127.0.0.1:6379[4]> hset user:1 name fanzhe
(integer) 1
127.0.0.1:6379[4]> hget user:1 name
“fanzhe”
#################################################################
Zset(有序集合)
在set基础上增加了一个值,set k1 v1 、 zset k1 score v1
#################################################################
- zadd myset 1 one
- zadd myset 2 two 3 three
- zrange myset 0 -1:查询所有
127.0.0.1:6379[5]> zadd myset 1 one #添加一个值
(integer) 1
127.0.0.1:6379[5]> zadd myset 2 two 3 three #添加多个值
(integer) 2
127.0.0.1:6379[5]> zrange myset 0 -1
- “one”
- “two”
- “three”
#################################################################
排序如何实现?
- zrangebyscore salary -inf +inf:显示从小到大的用户
- zrevrange salary 0 20000 :显示区间用户,从大到小
- zrangebyscore salary -inf +inf whthscores:显示区间内的用户和数据
127.0.0.1:6379[6]> zadd salary 2500 zhangsan #添加三个用户
(integer) 1
127.0.0.1:6379[6]> zadd salary 18000 fanzhe
(integer) 1
127.0.0.1:6379[6]> zadd salary 5000 xiaoming
(integer) 1
127.0.0.1:6379[6]> zrangebyscore salary -inf +inf #显示全部用户,从小到大排序
- “zhangsan”
- “xiaoming”
- “fanzhe”
127.0.0.1:6379[6]> zrangebyscore salary 0 20000 withscores #显示金额在0-20000 的用户和数据,从小到大 - “zhangsan”
- “2500”
- “xiaoming”
- “5000”
- “fanzhe”
- “18000”
127.0.0.1:6379[6]> zrevrange salary 0 20000 withscores - “fanzhe”
- “18000”
- “xiaoming”
- “5000”
- “zhangsan”
- “2500”
#################################################################
- zrem zset key:移除
- zcard salary :获取有序集合中元素个数
127.0.0.1:6379[6]> zrem salary xiaoming
(integer) 1
127.0.0.1:6379[6]> zrange salary 0 -1
- “zhangsan”
- “fanzhe”
127.0.0.1:6379[6]> zcard salary
(integer) 2
#################################################################
- zcount zset 0 2000:计算区间内成员数量
127.0.0.1:6379[6]> zcount salary 0 20000
(integer) 2
#################################################################
案例思路:
- set排序,存储班级成绩表,工资表排序
- 带权重就行排序
- 排行榜应用,Top N
#################################################################