Redis特性
- 速度快
内存、c语言、单线程 - 持久化
所有数据保持在内存中,对数据的更新将异步保存到磁盘上 - 多种数据结构
- 支持多种客户端语言
- 功能丰富
发布订阅、事务、Lua脚本、pipeline - 简单
23000行代码、不依赖外部库、单线程模型 - 主从复制
- 高可用、分布式
Redis典型应用场景
- 缓存系统
- 计数器
- 消息队列系统
- 排行榜
- 社交网络
- 实时系统
Redis安装
wget http://download.redis.io/releases/redis-3.0.7.tar.gz
解压并转到解压目录
ln -s redis-3.0.7 redis //创建软链接
make&&make install
Redis启动
- 简单启动
src/redis-server:开启redis服务端
src/redis-cli -h 127.0.0.1 -p 6379 客户端连接- 配置文件启动
src/redis-server config.conf
Redis API
通用命令
- keys(一般不在生产环境中使用,时间复杂度:O(n))
keys *
遍历所有的key
keys [pattern]
遍历符合正则的key - dbsize
dbsize
计算key的总数 - exists
exists key
检查key是否存在(1:0) - del
del key1 key2
删除指定的key-value - expire
expire key seconds
设置key在seconds秒后过期 - ttl
ttl key
查看key剩余的过期时间 - persist
persist key
去掉key的过期时间(-2代表key已经不存在;-1代表key存在且没有过期时间) - type
type key
返回key的类型
字符串
- 场景
缓存、计数器、分布式锁等 - api
get、set、del
setnx key value
key不存在才设置
set key value xx
key 存在才设置
incr key
key自增1,如果key不存在,自增后get(key)=1
decr key
key自减1,如果key不存在,自减后get(key)=-1
incrby key k
key自增1,如果key不存在,自增后get(key)=k
decrby key k
key自减k,如果key不存在,自减后get(key)=-k
mget key1 key2 key3
批量获取key
mset key1 value1 key2 value2
批量设置key-value
getset key newvalue
设置newvalue并返回旧的value
append key value
将value追加到旧的value
strlen key
返回字符串的长度(注意中文)
incrbyfloat key 3.5
增加key对应的值3.5
getrange key start end
获取字符串指定下标的所有值
setrange key index value
设置指定下标对应的值
哈希
- 哈希键值结构
key-->{field:value} field不能相同 - API
hget key field
获取hash对应key对应field的value
hgetall key
获取hash对应key的所有field和value
hset key field value
设置hash对应key对应field的value
hdel key field
删除hash对应key对应field的value
hexists key field
判断hash key是否有field
hlen key
获取hash key field的数量
hmget key field1 field2 field3
批量获取hash key对应的一批field对应的值
hmget key field1 value1 field2 value2
批量设置hash key的一批field value
hincrby key field count
增加整数,可填负数
hincrbyfloat key field count
增加浮点数,可填负数
hvals key
返回hash key对应的所有field对应的value
hkeys key
返回hash key对应的所有field
hsetnx key field value
field不存在才设置
列表
- 特点
有序、可重复、左右两边插入弹出 - API
rpush key value1 value2
从列表右端插入值
lpush key value1 value2
从列表左端插入值
linsert key before|after value newvalue
在list指定值得前后插入newvalue
lpop key
从list左侧弹出item
lrem key count value
根据value的值,从列表中删除所有与value相等的项
count>0从左到右;count<0从右到左;count=0删除所有
ltrim key start end
按照索引范围修建列表
lrange key start end
获取列表指定索引范围所有item
lindex key index
获取列表指定索引的item
llen key
计算列表的长度
lset key index newvalue
设置列表指定索引值为newvalue
Jedis
- Jedis(String host, int port, int connectionTimeout, int soTimeout)
(节点IP, 节点端口, 客户端连接超时, 客户端读写超时)
Jedis jedis = new Jedis("192.168.186.100",6380)
- String
jedis.set("hello","world");
jedis.get("hello");
jedis.incr("x");
- Hash
jedis.hset("user:1:info","address","广州");
jedis.hget("user:1:info","address");
jedis.hgetAll("user:1:info");
- List
jedis.rpush("list","4","5","8");
jedis.lpop("list");
jedis.lrange("list",0,-1);
- Set
jedis.sadd("set","a");
jedis.sadd("set","b","a");
jedis.sadd("set","a");
jedis.srem("set","a","b");
jedis.smembers("set");
- zset
jedis.zadd("myzset",80,"tom");
jedis.zadd("myzset",80,"jack");
jedis.zadd("myzset",90,"lili");
System.out.println(jedis.zrangeWithScores("myzset", 0, -1));
System.out.println(jedis.zrange("myzset", 0, -1));
`System.out.println(jedis.zcard("myzset"));`
慢查询
- 客户端请求redis生命周期
发送命令-->排队-->执行命令-->返回结果
慢查询发生在执行命令阶段
客户端超时不一定是慢查询,但慢查询是客户端超时的一个因素 - 特点
先进先出队列
固定长度
保存在内存中 - 参数
慢查询阈值(微秒):slowlog-log-slower-than
(0:记录所有;1:不记录)
最大长度:slowlog-max-len
config get 参数名
- 修改配置文件重启(不建议)
- 动态配置
config set 参数名
- 常用命令
slowlog get [n]
获取慢查询队列
队列信息
slowlog len
获取慢查询队列长度
slowlog reset
清空慢查询队列 - tips
slowlog-log-slower-than不要设置过大,通常设置1ms
slowlog-max-len不要设置过小,设置1000左右
理解命令生命周期
定期持久化
pipeline流水线
package com.test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
public class TestPipeline {
public static void main(String[] args) {
Jedis jedis = new Jedis("192.168.186.100",6380);
long start = System.currentTimeMillis();
// for (int i=0;i<10000;i++){
// jedis.hset("key","field"+i,"value"+i);//2260
// }
for (int i=0;i<=10;i++){
Pipeline pipeline = jedis.pipelined();
for (int j=i*1000;j<=(i+1)*100;j++){
pipeline.hset("key1","field"+j,"value"+j);//47
}
pipeline.syncAndReturnAll();
}
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
-对比原生的M命令
pipeline命令是非原子性的
- 注意事项
1、注意pipeline每次携带的数据量
2、pipeline每次只能作用在一个redis节点上
发布订阅
- 发布命令
publish channel message
返回订阅者个数` - 订阅命令
subscribe [channel]//一个或多个
psubscribe [pattern]//根据模式订阅
punsubscribe [pattern]//根据模式退订
pubsub channels//列出至少有1个订阅者的频道
pubsub numsub [channel..]//列出指定频道订阅者的数量
网友评论