1,查看全部键:keys * set school dongnao set hello worldjava
2,键总数 dbsize //2个键,若是存在大量键,线上禁止使用此指令redis
3,检查键是否存在:exists key //存在返回1,不存在返回0spring
4,删除键:del key //del hello school, 返回删除键个数,删除不存在键返回0sql
5,键过时:expire key seconds //set name test expire name 10 //10秒过时数据库
ttl 查看剩余的过时时间编程
6,键的数据结构类型:type key //type hello //返回string,键不存在返回none缓存
7,flushall 清空全部数据 flushdb 清空当前库数据,redis单机环境下有16个库(0-15)网络
列举例子:三个客户端同时执行命令数据结构
客户端1:set name test架构
客户端2:incr num
客户端3:incr num
执行过程:发送指令-〉执行命令-〉返回结果
执行命令:单线程执行,全部命令进入队列,按顺序执行,使用I/O多路复用解决I/O问题,后面有介绍(因为读写操做等待用户输入或输出都是阻塞的,因此 I/O 操做在通常状况下每每不能直接返回,这会致使某一文件的 I/O 阻塞致使整个进程没法对其它客户提供服务 ,IO多路复用模型是创建在内核提供的多路分离函数select基础之上的,使用select函数能够避免同步非阻塞IO模型中轮询等待的问题)
单线程快缘由:纯内存访问, 非阻塞I/O(使用多路复用),单线程避免线程切换和竞争产生资源消耗
问题:若是某个命令执行,会形成其它命令的阻塞
1,字符串类型:
实际上能够是字符串(包括XML JSON),还有数字(整形 浮点数),二进制(图片 音频 视频),最大不能超过512MB
2,设值命令:
set age 23 ex 10 //10秒后过时 px 10000 毫秒过时
setnx name test //不存在键name时,返回1设置成功;存在的话失败0
set age 25 xx //存在键age时,返回1成功
场景:若是有多客户同时执行setnx,只有一个能设置成功,可作分布式锁
3.获值命令:
get age //存在则返回value, 不存在返回nil
4.批量设值:
mset country china city beijing
5.批量获取:
mget country city address //返回china beigjin, address为nil
若没有mget命令,则要执行n次get命令
使用mget=1次网络请求+redis内部n次查询
6.计数:
incr age //必须为整数自加1,非整数返回错误,无age键从0自增返回1
decr age //整数age减1
incrby age 2 //整数age+2
decrby age 2//整数age -2
incrbyfloat score 1.1 //浮点型score+1.1
7.append追加指令:
set name hello; append name world //追加后成helloworld
8.字符串长度:
set hello “世界”;strlen hello//结果6,每一个中文占3个字节
9.截取字符串:
set name helloworld ; getrange name 2 4//返回 llo
10.内部编码:
int: 8字节长整理//set age 100; object encoding age //返回int
embstr: 小于等于39字节串set name bejin; object encodeing name//embstr
raw: 大于39字节的字符串set a fsdfwerwerweffffffffffdfs//返回raw
Ps:
Flushall清除全部数据 flushdb 清库
redis 单点环境下有16个库 select 15 能够切换到第15个数据库 集群只有一个数据库0
1.键值设计:
业务名:对象名:id:[属性],数据库为order, 用户表user,对应的键可为 order:user:1 或order:user:1:name
注意:
redis目前处于受保护模式,不容许非本地客户端连接,能够经过给redis设置密码,而后客户端连接的时候,写上密码就能够了
127.0.0.1:6379> config set requirepass 123456 临时生效
或者修改redis.conf requirepass 123456,启动时./redis-server redis.conf指定conf
./redis-cli -p 6379 -a 12345678 //须要加入密码才能访问
切换数据库:
select 2
场景实践cache-demo
JedisAllCommandTest OrderListHashTest SiteVisitNumTest
redis通用工具类
public class JedisUtils { private JedisPool pool = null; //具体使用见java代码 }
jedis缓存工具类,使用redisTemlate处理
@Component public class RedisUtil { // spring 对redis操做的封装,使用了模板模式 @Resource private RedisTemplate<String, Object> template; }
Spring的配置
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="100" /> <property name="maxIdle" value="10" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"> <property name="hostName" value="192.168.1.111" /> <property name="port" value="6379" /> <property name="database" value="2" /> <property name="timeout" value="3000" /> <property name="usePool" value="true" /> <property name="password" value="12345678"/> <property name="poolConfig" ref="jedisPoolConfig" /> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> <property name="keySerializer" ref="stringRedisSerializer"/> <property name="valueSerializer" ref="stringRedisSerializer"/> <property name="enableTransactionSupport" value="false"></property> </bean> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id ="JdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/> <bean id="GenericToStringSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer" c:type="java.lang.Long"/> <cache:annotation-driven/> <!-- declare Redis Cache Manager --> <bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg index="0" ref="redisTemplate"></constructor-arg> </bean>
是一个string类型的field和value的映射表,hash特适合用于存储对象。
命令 hset key field value
设值:hset user:1 name james //成功返回1,失败返回0
取值:hget user:1 name //返回james
删值:hdel user:1 age //返回删除的个数
计算个数:hset user:1 name james; hset user:1 age 23;
hlen user:1 //返回2,user:1有两个属性值
批量设值:hmset user:2 name james age 23 sex boy //返回OK
批量取值:hmget user:2 name age sex //返回三行:james 23 boy
判断field是否存在:hexists user:2 name //若存在返回1,不存在返回0
获取全部field: hkeys user:2 // 返回name age sex三个field
获取user:2全部value:hvals user:2 // 返回james 23 boy
获取user:2全部field与value:hgetall user:2 //name age sex james 23 boy值
增长1:hincrby user:2 age 1 //age+1
hincrbyfloat user:2 age 2 //浮点型加2
内部编码
ziplist<压缩列表>和hashtable<哈希表>
当field个数少且没有大的value时,内部编码为ziplist
如:hmset user:3 name james age 24; object encoding user:3 //返回ziplist
当value大于64字节,内部编码由ziplist变成hashtable
如:hset user:4 address “fsgst64字节”; object encoding user:3 //返回hashtable
应用场景
好比将关系型数据表转成redis存储:
HASH类型是稀疏,每一个键能够有不一样的filed, 若用redis模拟作关系复杂查询开发因难,维护成本高
三种方案实现用户信息存储优缺点
1.原生:
set user:1:name james;
set user:1:age 23;
set user:1:sex boy;
优势:简单直观,每一个键对应一个值
缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境
2.将对象序列化存入redis
set user:1 serialize(userInfo);
优势:编程简单,若使用序列化合理内存使用率高
缺点:序列化与反序列化有必定开销,更新属性时须要把userInfo全取出来进行反序列化,更新后再序列化到redis
3.使用hash类型
hmset user:1 name james age 23 sex boy
优势:简单直观,使用合理可减小内存空间消耗
缺点:要控制ziplist与hashtable两种编码转换,且hashtable会消耗更多内存
总结:对于更新很少的状况下,可使用序列化,对于VALUE值不大于64字节可使用hash类型
用来存储多个有序的字符串,一个列表最多可存2的32次方减1个元素
由于有序,能够经过索引下标获取元素或某个范围内元素列表,列表元素能够重复
列表命令
添加命令
rpush james c b a //从右向左插入cba, 返回值3 lrange james 0 -1 //从左到右获取列表全部元素 返回 c b a lpush key c b a //从左向右插入cba linsert james before b teacher //在b以前插入teacher, after为以后,使用lrange james 0 -1 查看:c teacher b a
查找命令
lrange key start end //索引下标特色:从左到右为0到N-1 lindex james -1 //返回最右末尾a,-2返回b llen james //返回当前列表长度 lpop james //把最左边的第一个元素c删除 rpop james //把最右边的元素a删除 lrem key count value//删除指定元素
应用场景设计: cacheListHashApplicationTest用例
每一个用户有多个订单key为 order:1 order:2 order:3, 结合hmset
hmset order:1 orderId 1 money 36.6 time 2018-01-01 hmset order:2 orderId 2 money 38.6 time 2018-01-01 hmset order:3 orderId 3 money 39.6 time 2018-01-01
把订单信息的key放到队列
lpush user:1:order order:1 order:2 order:3
每新产生一个订单,
hmset order:4 orderId 4 money 40.6 time 2018-01-01
追加一个order:4放入队列第一个位置
lpush user:1:order order:4
当须要查询用户订单记录时:
List orderKeys = lrange user:1 0 -1 //查询user:1 的全部订单key值
for(Order order: orderKeys){ hmget order:1 }
列表内部编码:
1,当元素个数少且没大元素,编码为ziplist,减小内存的使用
rpush list a b c
object encoding list //返回ziplist
2,当元素超过512个,或元素超过64字节,内部编码变成linkedlist链表;
rpush list a1 a2 ....a513 或rpush list xxxxxxxxxxxxxx
object encoding list //linkedlist
保存多元素,与列表不同的是不容许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集;
命令:
exists user //检查user键值是否存在
sadd user a b c //向user插入3个元素,返回3
sadd user a b //若再加入相同的元素,则重复无效,返回0
smember user //获取user的全部元素,返回结果无序
srem user a //返回1,删除a元素
scard user //返回2,计算元素个数
sismember user a //判断元素是否在集合存在,存在返回1,不存在0
srandmember user 2 //随机返回2个元素,2为元素个数
spop user 2 //随机返回2个元素a b,并将a b从集合中删除
smember user //此时已没有a b, 只有c
集合的交集:
sadd user:1 zhangsan 24 girl
sadd user:2 james 24 boy //初始化两个集合
sinter user:1 user:2 //求两集合交集, 此时返回24
sadd user:3 wang 24 girl //新增第三个元素
sinter user:1 user:2 user:3 //求三个集合的交集,此时返回24
集合的并集(集合合并去重):
sunion user:1 user:2 user:3 //三集合合并(并集),去重24
sdiff user:1 user:2 //1和2差集,(zhangsan 24 girl)-(james 24 boy)=zhangsan girl
将交集(jj)、并集(bj)、差集(cj)的结果保存:
sinterstore user_jj user:1 user:2 //将user:1 user:2的交集保存到user_jj
sunionstore user_bj user:1 user:2 //将user:1 user:2的(并)合集保存user_bj
sdiffstore user_cj user:1 user:2 //将user:1-user:2的差集保存user_cj
smemebers user_cj // 返回zhangsan girl
内部编码:
sadd user 1 2 3 4 //当元素个数少(小于512个)且都为整数,redis使用intset减小内存的使用
sadd user 1 2...513 //当超过512个或不为整数(好比a b)时,编码为hashtable
object encoding user //hashtables
使用场景:
标签,社交,查询有共同兴趣爱好的人,智能推荐
使用方式:给用户添加标签:
sadd user:1:fav basball fball pq
sadd user:2:fav basball fball
............
或给标签添加用户
sadd basball:users user:1 user:3
sadd fball:users user:1 user:2 user:3
........
计算出共同感兴趣的人:
sinter user:1:fav user2:fav
规则:
sadd (经常使用于标签) spop/srandmember(随机,好比抽奖)
sadd+sinter (用于社交,查询共同爱好的人,匹配)
与集合有联系,不能有重复的成员
与LIST SET 对比
命令
zadd key score member [score member......]
zadd user:zan 200 james //james的点赞数1, 返回操做成功的条数1
zadd user:zan 200 james 120 mike 100 lee // 返回3
zadd test:1 nx 100 james //键test:1必须不存在,主用于添加
zadd test:1 xx incr 200 james //键test:1必须存在,主用于修改,此时为300
zadd test:1 xx ch incr -299 james //返回操做结果1,300-299=1
zrange test:1 0 -1 withscores //查看点赞(分数)与成员名
zcard test:1 //计算成员个数, 返回1
查点赞数
zadd test:2 nx 100 james //新增一个集合
zscore test:2 james //查看james的点赞数(分数),返回100
排名:
zadd user:3 200 james 120 mike 100 lee //先插入数据
zrange user:3 0 -1 withscores //查看分数与成员
lee |
mike |
james |
100 |
120 |
200 |
zrank user:3 james //返回名次:第3名返回2,从0开始到2,共3名
zrevrank user:3 james //返回0, 反排序,点赞数越高,排名越前
删除成员:
zrem user:3 jame mike //返回成功删除2个成员,还剩lee
增长分数:
zincrby user:3 10 lee //成员lee的分数加10
zadd user:3 xx incr 10 lee //和上面效果同样
返回指定排名范围的分数与成员
zadd user:4 200 james 120 mike 100 lee //先插入数据
zrange user:4 0 -1 withscores //返回结果以下图
zrevrange user:4 0 -1 withscores //倒序,结果以下图
返回指定分数范围的成员
zrangebyscore user:4 110 300 withscores //返回120 lee ,200 James, 由低到高
zrevrangebyscore user:4 300 110 withscores //返回200james 120lee,由高到低
zrangebyscore user:4 (110 +inf withscores //110到无限大,120mike 200james
zrevrangebyscore user:4 (110 -inf withscores //无限小到110,返回100 lee
返回指定分数范围的成员个数:
zcount user:4 110 300 //返回2,由mike120和james200两条数据
删除指定排名内的升序元素:
zremrangebyrank user:4 0 1 //分数升序排列,删除第0个与第1个,只剩james
删除指定分数范围的成员
zadd user:5 200 james 120 mike 100 lee //先插入测试数据
zremrangebyscore user:5 100 300 //删除分数在100与300范围的成员
zremrangebyscore user:5 (100 +inf //删除分数大于100(不包括100),还剩lee
有序集合交集:
格式:zinterstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
destination:交集产生新的元素存储键名称
numkeys: 要作交集计算的键个数
key :元素键值
weights:每一个被选中的键对应值乘weight, 默认为1
初始化数据:
zadd user:7 1 james 2 mike 4 jack 5 kate //初始化user:7数据
zadd user:8 3 james 4 mike 4 lucy 2 lee 6 jim //初始化user:8数据
交集例子:
zinterstore user_jj 2 user:7 user:8 aggregate sum
//2表明键合并个数,aggregate sum可加也不可加上,由于默认是sum结果user_jj:4james(1+3), 6mike(2+4)
zinterstore user_jjmax 2 user:7 user:8 aggregate max 或min
//取交集最大的分数,返回结果 3james 4mike, min取最小
weights:
zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max
//1,取两个成员相同的交集,user:7->1 james 2 mike; user:8->3 james 4 mike
//2,将user:7->james 1*8=8, user:7->mike 2*8 =16, 最后user:7结果 8 james 16 mike;
//3,将user:8-> james 3*4=12, user:8->mike 4*4=16 最后user:8结果12 james 16 mike
//4,最终相乘后的结果,取最大值为 12 james 16mike
//5, zrange user_jjweight 0 -1 withscores 查询结果为 12 james 16mike
总结:将user:7成员值乘8,将user:8成员值乘4,取交集,取最大
有序集合并集(合并去重):
格式:zunionstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
destination:交集产生新的元素存储键名称
numkeys: 要作交集计算的键个数
key :元素键值
weights:每一个被选中的键对应值乘weight, 默认为1
zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max
//与以上zinterstore同样,只是取并集,指令同样
有序集合内部编码
object encoding user:init
//当元素个数少(小于128个),元素值小于64字节时,使用ziplist编码,可有效减小内存的使用
2,skiplist: zadd user:10 20 james......
//大于128个元素或元素值大于64字节时为skiplist编码
使用场景:
排行榜系统,如视频网站须要对用户上传的视频作排行榜
点赞数:zadd user:1:20180106 3 mike //mike得到3个赞
再获一赞:zincrby user:1:20180106 1 mike //在3的基础上加1
用户做弊,将用户从排行榜删掉:zrem user:1:20180106 mike
展现赞数最多的5个用户:zrevrangebyrank user:1:20180106 0 4
查看用户赞数与排名: zscore user:1:20180106 mike zrank user:1:20180106 mike