Redis相关知识
1.端口6379
2.默认16个数据库,类似数组,下标从0开始,初始默认使用0号数据库。
3.所有数据库相同的密码
开启redis redis-cli
set a a | set设置键值对,键:a,值:a |
---|---|
get a | get查看键的值,查看到a的值 |
select 1 | select选择1号数据库 |
get a | 在当前数据库不能访问键:a |
nil | nil相当于java中的null |
select 0 | select选择0号数据库 |
get a | get查看键的值,查看到a的值 |
串行 | 事务的隔离级别,将你的请求串连起来,一个一个去处理。只有这个请求处理了,下一个请求才能被处理 |
---|---|
多线程+锁 | memcached里面处理请求的方式 |
单线程+多路IO复用 | Redis里面处理请求的方式 |
Redis是单线程的,为什么读写速度那么快,因为它除了单线程还有多路IO复用
多路复用指的是用一个线程检查多个文件描述符的就绪状态
多个请求同时去访问Redis的时候,全部请求都加一个监视的效果,
监视这个请求是否准备完毕,如果请求准备完毕,直接让Redis对这个请求进行处理。
总结:
1.虽然只有一个线程让Redis进行处理请求,但是可以监视这个请求是否准备完毕,如果请求准备完毕,直接让Redis对这个请求进行处理。
2. Redis没有阻塞状态,将一直对这个请求进行处理,因为它处理的请求全部是准备完毕的。
IO复用又包括select,poll,epoll模式。
select模式会一个一个去跟请求进行通信 |
---|
问问这个请求准备完成没,准备完成的交给Redis去处理,没有准备完成的,去问下一个请求。最多监视1024个请求。 |
pop模式,监视请求没有数量限制 |
epoll模式监视请求的时候,会给请求设置标识符,写的是是否准备完毕,只要准备完毕,就让redis进行处理。 |
Redis数据类型
五种数据类型是对值来说的。
string set list hash zset
key是键
hashmap里面还有键
keys * | 查看当前数据库所有的键 |
---|---|
exists key | 查看当前数据库是否有某一个键 |
type key | 查看当前键的数据类型 |
del key | 删除某一个键 |
expire key seconds | 为键设置过期时间 |
---|---|
ttl key | 查看当前键还有多少秒过期,-1表示永不过期,-2表示已过期 |
keys * | 无过期的键 |
dbsize | 查看当前数据库key的数量 |
---|---|
flushdb | 清空当前数据库 |
flushall | 通杀全部数据库 |
String --redis最基本的类型,就是一个键值对。value最多512M
String是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。
如果要把一个对象存进redis里面,这个对象必须序列化。
get k1 | get查看键的值,查看到k1的值 |
---|---|
apend key value | apend给键的值后面追加 |
strlen key | strlen获得键的值的长度 |
strnx key value | strnx为不存在的键赋值 |
incr key | incr给键的值原子加1 |
---|---|
decr key | decr 给键的值原子减1 |
incrby key 步长 | incr给键的值原子加任意步长 |
decrby key 步长 | decrby 给键的值原子减任意步长 |
原子性
所谓原子操作是指不会被线程调度机制打断的操作。 |
---|
这种原子操作一旦开始,就一直运行到结束,中间不会有任何context switch(切换到另一个线程) |
单线程中,单条指令中完成的操作都被认为是原子操作
多线程中,不能被其他线程打断的操作就叫原子操作
Redis单命令的原子性主要得益于 Redis的单线程。
java中的i++是否是原子操作?
i++的操作步骤为取出i、自增1、存入i;
这三个阶段中间都可以被中断分离开的,所以i++不是原子操作
mset k4 v4 k5 v5 | mset同时设置多个键值对 |
---|---|
mget k1 k2 k3 | mget同时获取多个键的值 |
msetnx k1 v1 k6 v6 | msetnx同时为多个不存在的键赋值 |
getrange k1 0 2 | getrange获取某一范围键的值 |
---|---|
setrange k1 2 abc | setrange从这个范围开始,设置键的值 |
setex k1 10 v1 | setex设置键值对的同时,设置过期时间 |
---|---|
getset k1 v2 | getset设置键的值的时候,返回原来的值。 |
List
单键多值,但是值的类型还是string。
按照插入顺序排序。
你可以添加一个元素到列表的头部或者尾部。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
lpush testList a b c d e | 插入到链表的头部 |
---|---|
rpush testList 1 2 3 4 5 | 插入到链表的尾部 |
lpop testList | 从链表的头部弹出来数据 |
rpop testList | 从链表的尾部弹出来数据 |
rpoplpush testList testListTwo | 从链表1的尾部弹出来数据 ,插入到链表2的头部 |
lrange testList 0 -1 | 根据这个索引范围来查询数据,从左到右 |
---|---|
lindex testList -1 | 获得这个索引所对应的元素 |
llen testList | 获得链表的长度 |
linsert testList before 1 xyz | 在1之前插入元素 |
---|---|
lrem testList 0 1 | 从链表左边/右边/全部删除n个value |
**Redis set 对外提供的功能,与list类似,是一个列表的功能
set是可以自动排重
set提供了判断某个成员是否在一个set集合内的重要接口
Redis的set,
是string类型的无序集合。
它底层其实是一个value为null的hash表
所以添加,删除,查找的复杂度都是O(1)
sadd testSet1 a b c d e 1 2 3 | sadd把多个元素加入到集合中 |
---|---|
smembers testSet1 | smembers返回该集合的所有值 |
sismember testSet x | sismember看看集合中是否有某个元素 |
scard testSet1 | 返回该集合的元素个数 |
---|---|
srem testSet1 a 1 | 删除集合的某个元素 |
spop testSet1 | 随机从集合中吐出一个值 ,不会删 |
srandmember testSet 1 3 | 随机从集合中吐出几个值,不会删 |
sinter testSet1 testSet2 | 两个集合的交集元素 |
---|---|
sunion testSet1 testSet2 | 两个集合的并集元素 |
sdiff testSet1 testSet2 | 两个集合的差集元素 |
Redis中的hash
其实是个string类型的键值对集合 |
---|
特别适合存储对象 |
类似 Java里面的Map<String,String> |
用户的ID作为键
实体类对象,给每个属性赋完值之后,就可以对它进行序列化,把他保存到我们的redis里面。
ID为键,序列化对象为值。
用不到hash数据类型,用string就行了,一个对象一个值。
一个key来存储用的用户的一个信息(姓名)
另外一个key再来存储用的用户的其他信息(年龄)
键冲突,把原来的值覆盖掉。
比如说你用手机作为键来存储我们的验证码,但是有时手机作为键,来存储其他信息。
hset userInfo user:1010:uid 1010 | 在userInfo里面创建了一个key,这个key叫user:1010:uid,存储用户的uid |
---|---|
hmset userInfo user:1010:username admin user:1010: password 123456 | 在userInfo里面创建了多个key |
hget userInfo user:1010:username | 获取userInfo里面的这个key的值 |
hgetall userInfo | 获取userInfo里面的键值对 |
hsetnx userInfo user:1010:sex boy | 在userInfo里面创建了一个key,这个key叫user:1010:uid,存储用户的性别 |
hexists userInfo user:1010:uid | 在userInfo里面是不是存在这样一个key |
---|---|
hkeys userInfo | 遍历在userInfo里面所有的key |
hvals uerInfo | 遍历在userInfo里面所有的key的值 |
hincrby userInfo user:1000:age 10 | 为userInfo的这个key,key的值加10 |
---|
zset (sorted set)
(Redis里面不管你用哪种数据类型存储,里面的都是字符串)
zset | set | |
---|---|---|
相同 | 1.没有重复元素的,2.字符串集合。 | 1.没有重复元素的,2.字符串集合。 |
不相同 | 有序集合的每个成员都关联了一个分数(score),为啥它有序,因为它比的是分数(score) | 普通集合 |
zadd testzSet 100 a 20 b 1 x 500 abc | 向有序集合 testzSet添加元素,前面是分数,后面是元素 |
---|---|
zrange testzSet 0 -1 | 查询有序集合 testzSet中的元素,元素按照分数来排序 |
zrevrange testzSet 0 -1 | 查询有序集合 testzSet中的元素,元素按照分数来倒序 |
zrangebyscore testzSet 1 200 | 通过分数范围来查询元素 |
zrangebyscore testzSet 100 100 | 通过分数范围来查询元素(一个) |
zincrby testzSet 100 b | 为元素b的分数加上100 |
---|---|
zrem testzSet 100 | 在有序集合 testzSet中,删除指定分数的元素 |
zcount testzSet 1 100 | 在有序集合 testzSet中,统计指定分数范围的元素 |
zrank testzSet 100 | 返回分数排名 |
如何利用zset 实现一个文章访问量的排序
zadd text 100 java 200 python 20 php
zrevrange text 0 -1