一、通用命令
keys 命令一般不在生产环境中使用。
-
keys怎么用?
- 热备从节点
- scan
-
dbsize
- 计算key的总数 。时间复杂度为O(1)。是redis内置的一个命令
-
exists key
- 检查 key 是否存在。存在:1, 不存在:0
-
del
- 删除指定 key-value
-
expire key seconds
- key 在seconds秒后过期
-
ttl key
- 查看key剩余的过期时间
-
persist key
- 去掉key的过期时间
-
type
- 返回key的类型
二、 数据结构与内部编码
redis是一个内存的数据库,对于内存来说还是比较珍贵的。我们可以使用一些压缩的结构
三、单线程
redis在一个瞬间只会执行一个命令。即是单线程的。
那么redis的单线程为什么这么快呢?
- 纯内存
- 非阻塞IO
将epoll的事件连接转换为自己的内部处理。不再网络IO上浪费太多时间
-
避免线程切换和竞态消耗
-
一次只运行一条命令
-
拒绝长(慢)命令
-
keys , flushall, flushdb, slow lua script, mytil/exec, operate big value(collection)
四、字符串类型
本质上,value都是二进制的,限制大小:最大是512MB
-
场景
- 缓存
- 计数器
- 分布式锁
-
[incr key]
- key 自增1,如果key不存在,自减后get(key) = -1
实战!
1.实现如下功能:
记录网站每个用户个人主页的访问量?
incr userid: pageview(单线程:无竞争)
2. 实现如下功能:
缓存视频的基本信息(数据源在MySQL中)伪代码
[set] [setnx] [setxx]
set key value
: 不管key是否存在,都设置setnx key value
:必须key不存在,才能设置setxx key value
:key存在,才设置
使用mget可以节省大量的网络时间。
- [getset]
- set key newvalue 并返回旧的value
- [append]
- 将value追加到旧的value
- [strlen]
- 返回字符串的长度(注意中文)
五、哈希类型
5.1 特点
field 不能相同,value可以相同
5.2 重要的API
所以hash的命令都是以H开头
- [
hget key field
]- 获取 hash key 对应的 field 的 value
-
hdel
-
hexists key filed
- 判断hash key 是佛有field
-
hlen
- 获取hash key field 的数量
-
hmget key field1 field2…fieldN
- 批量获取 hash key 的一批 field对应的值
-
hmset key fields1 value1 field2 value2…fieldN valueN
- 批量设置 hash key的一批 field value
实战1!
实现如下功能: 记录网站每个用户个人主页的访问量?
hincrby user:1:info pageview count
实战2!
实现如下功能:
缓存视频的基本信息(数据源在mysql中)
5.3 hash vs string
5.4 用户信息(String实现)
方法一:
方法二:这种方法不利于集中管理,好处是可以更新一条指令。
方法三:
三种方案的比较
方法一:节约内存是因为使用了序列化
5.5 总结
六、 list类型
6.1 列表结构:
6.2 重要API
-
repush key value1 value2 ... valueN
- 从列表右端插入值(1-N个)
-
linsert key before | after value newValue
- 在list指定的值前 | 后 插入newValue
-
lpop key
- 从列表左侧弹出一个item
-
rpop key
- 从列表右侧弹出一个item
-
lrem key count value
- 根据count值,从列表中删除所有value相等的项
-
ltrim key start end
- 按照索引范围修剪列表
-
lrange key start end
- 获取列表指定索引范围所有item
-
lindex key index
- 获取列表指定索引 index
-
llen key
- 获取列表长度
-
lset key index newValue
- 设置列表指定索引值为 newValue
6.3 实战
微博的TimeLine
6.4 查缺补漏
LPUSH + LPOP = Stack
LPUSH + RPOP = Queue
LPUSH + LTRIM = Capped Collection
LPUSH + BRPOP = Message Queue
七、set
7.1 特点
无序
无重复
集合间操作
7.2 API
-
sadd key element
- 向集合key添加element(如果element已经存在,添加失败)
-
srem key element
- 将集合key中的element移除
-
spop
- 从集合弹出一个元素
-
srandmember
- 不会破坏集合结构,可以从集合中随机返回多个元素
-
sinter
-
sdiff
-
sunion
-
scard
-
susnenver
-
smembers
- 返回结果是无序的
- 小心使用
-
SADD
- 可以做一些标签
实战!
- 抽奖系统
- like 赞 踩
- 共同关注的人
九、Redis客户端
9.1 获取Jedis
命令行是shell的redis客户端
Jedis是java的redis客户端
9.2 Jedis基本使用
-
生成一个Jedis对象,这个对象负责和指定Redis结点进行通信
- Jedis jedis = new Jedis(“127.0.0.1”,6379);
-
jedis执行set操作
- jedis.set(“hello”,“world”) ;
-
jedis执行get操作
- String value = jedis.get(“hello”);
-
Jedis(String host, int port, int connectionTimeouit, int soTimeout)
- host:Redis结点的所在机器的 IP
- port:Redis结点的端口
- connectionTimeout:客户端连接超时
- soTimeout:客户端读写超时
Jedis直连的执行过程
- 【步骤一】生成Jedis对象
- 【步骤二】Jedis执行命令
- 【步骤三】返回执行结果
- 【步骤四】关闭Jedis连接
9.3 Jedis连接池使用
9.4 直连与连接池两种方案的对比
9.5 Jedis线程池的使用
如果使用的是jedis.close,这里面不是关闭连接,而是将线程归还到线程池。