默认配置:redis-server
运行配置:redis--server --configKey1 configValue1 --configKey2 configValue2
配置文件启动:redis-server /root/yangf/redis-4.0.6/redis.conf
生产环境中建议使用第三种启动。
交互式方式:redis-cli -h {host} -p {port}
命令行方式:redis-cli -h {host} -p {port} {command}
基本命令:redis-cli shutdown
采用kill:kill redis进程 ---但是不能采用kill -9 redis进程
1.查看所有的键 keys *
2.键总数 dbsize
3.检查键是否存在 exists key
4.删除键 del key [key ...]
5.键过期 expire key seconds
expireat key timestamp (2018.09.18 10:10:10--1537150210000)
pexpire key milliseconds
pexpireat key milliseconds-timestamp (毫秒级在redis2.6后提供)
清除键的过期时间 persist key
①若key不存在,返回结果0;
②若过期时间为负值,则相当于del命令;
③执行set命令会去掉过期时间,研发时需要特别注意;
④redis不支持二级数据结构的内部元素过期功能;
⑤setex == set expire ,原子执行,减少网络通讯时间。
6.查看键剩余时间 ttl key
pttl key
≥0:剩余的过期时间;-1:未设置过期时间;-2:键不存在。
7.查看键的数据结构类型 type key
8.键重命名 rename key newkey
renamenx key newkey
①若newkey已经存在,rename会将其覆盖,建议用rnamenx!
②重命名期间底层会执行del命令,若键对应的值比较大,有可能能会造成堵塞。
9.随机返回一个键 randomkey
10迁移键 ①move key db --用于数据库内部,生产环境不建议
②dump key
restore key ttl value
--redis实例之间,非原子性,不支持多个键
③migrate host port key|”” destination-db timeout [copy] [replace] [keys key [key ...]]
--redis实例之间,原子性,支持多个键
11. 全量遍历键 keys pattern
①pattern支持glob风格通配符;
②想删除所有以video字符串开头的键 redis-cli keys video* | xargs redis-cli del
12.渐进式遍历键 scan cursor [match pattern] [count number]
①解决面向哈希、集合、有序集合的扫描命令 hgetall -- hscan smembers -- sscan zrange -- zscan
②可解决keys命令产生的堵塞问题,但不能保证完整遍历所有键,具体开发时需要考虑情况。
实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,redis会在合适的场景选择合适的编码,通过object encoding查看内部编码,这样做有两个好处:①可以改进内部编码,可保证对外的数据结构和命令没有影响;②多种内部编码实现可以在不同场景下发挥各自优势。
字符串类型的值实际上可以是字符串(简单字符串+复杂字符串JSON、XML等)、数字、甚至是二进制(图片、音频、视频),但是值不能超过512MB。
◎设置值 set key value [ex seconds] [px milliseconds] [nx|xx]
--ex与px都是用来设置过期时间的,代表秒级和毫秒级
--nx 键必须不存在,用于添加
--xx 键必须存在,用于更新
setex key seconds value == set key value nx 可作为分布式锁的实现方案
setnx key value == set key value xx
◎获取值 get key --键不存在返回nil
◎批量设置值 mset key value [key value ...]
◎批量获取值 mget key [key ...]
◎计数 incr key
decr key
decrby key increment
incrby key increment
incrbyfloat key increment
--值不是整数,返回错误
--键不存在,按照值为0处理
◎追加值 append key value
◎字符串长度 strlen key (中文占用3字节)
◎设置并返回原值 getset key value
◎设置指定位置字符 setrange key offset value
◎获取部分字符串 get key start end
◎int :8个字节的长整形 set key 8653 + object encoding key
◎embstr:≤39个字节的字符串 set key “hello,zters!” + object encoding key
◎raw:>39个字节的字符串
①缓存功能:(防止键冲突和有助可维护性,推荐使用 业务名:对象名:id:[属性])
public UserInfo getUserInfo(long id)
{
String userRedisKey = "user:info:" + id;
Object value = redis.get(userRedisKey);
UserInfo userInfo;
if(null != value)
{
userInfo = deserialize(value);
}
else
{
userInfo = mysql.get(id);
if(null != userInfo )
{
redis.setex(userRedisKey, 3600, serialize(userInfo ));
}
}
return userInfo ;
}
②计数:(视频播放数等)
public long incrVideoCounter(long id)
{
String key = "video:playCount:" + id;
return redis.incr(key);
}
③共享session;
④短信验证码限速(限制一个IP地址不能在一秒内访问n次)
String phoneNum = "18252060161";
String key = "shoortMsg:limit:" + phoneNum;
Object isExists = redis.set(key, 1, "ex 60", "nx");
if(null != isExists || redis.incr(key) <= 5)
{
//通过
}
else
{
//不通过
}
哈希类型键值本身又是一个键值对结构。
◎设置值 hset key field value (有类似hsetnx命令,和前面的功能一样)
◎获取值 hget ket field
◎删除field hdel key field [field...]
◎计算field 个数 hlen key
◎批量设置或获取field-value hmget key field [field ...]
hmset key field value [field value ...]
◎判断field是否存在 hexists key field
◎获取所有field hkeys key
◎获取所有value hvals key
◎获取所有field-value hgetall key
--使用hgetall时,若哈希元素过多,有堵塞可能
--若只获取部分field,可使用hmget
◎计数 hincrby key field
hincrbyfloat key field
◎计算value长度 hstrlen key field
◎ziplist(压缩列表) :哈希元素个数<512&&值都<64, 节省内存;
◎hashtable(哈希表):不满足ziplist条件。
关系型数据库数据转换为redis数据库,比如缓存用户信息
public UserInfo getUserInfoByDB(long id)
{
String userRedisKey = "user:info:" + id;
Map userInfoMap = redis.hgetAll(userRedisKey);
UserInfo userInfo;
if(null != userInfoMap)
{
userInfo = transferMapToUserInfo(userInfoMap);
}
else
{
userInfo = mysql.get(id);
if(null != userInfo )
{
redis.hmset(userRedisKey,transferMapToUserInfo(userInfoMap));
redis.expire(userRedisKey, 3600);
}
}
return userInfo ;
}
一个列表最多可以存储-1个元素,对两端可以插入和弹出,可充当栈和队列。
◎右边插入 rpush key value [value ...]
◎左边插入 lpush key value [value ...]
◎某处插入 linsert key before|after pivot value
◎查找 lrange key start end (0→N-1)
◎获取指定下标元素 lindex key index
◎获取列表长度 llen key
◎从右侧弹出 rpop key
◎从左侧弹出 lpop key
◎删除指定元素 lrem key count value
--count>0,从左到右删除最多count个元素;
--count<0,从右到左删除最多count个元素;
--count=0,删除所有元素;
◎按照范围截取列表 ltrim key start end
◎修改指定下标的元素 lset key index newValue
◎堵塞操作 blpop key [key ...] timeout
brpop key [key ...] timeout
◎ziplist(压缩列表) :列表元素个数<512&&值都<64, 节省内存;
◎linkedlist(链表):不满足ziplist(压缩列表)时。
①消息队列:使用lpush+brpop组合实现;
②文章列表:每个用户有自己的文章列表,分页展示文章列表
a 每篇文章使用哈希结构存储
hmset article:1 title xx timstamp 1476536196 content xxxx
.......
hmset article:n title xx timstamp 1476539638 content xxxx
b 向用户文章列表添加文章
lpush user:1:articles article:1 article:3 article:16
.....
lpush user:k:articles article:45 article:85 article:92
c 分页获取用户文章列表
articles = lrange user:1:articles 0 9
for article in {articles}
hgetall {article}
集合中不允许有重复元素,且集合元素无序,最多可以存储 -1个元素,支持集合内的增删改查,还支持集合间交并差。
◎添加元素 sadd key element [element ...]
◎删除元素 srem key element [element ...]
◎计算元素个数 scard key
◎判断元素是否在集合中 sismember key element
◎随机从集合返回指定个数元素 srandommenber key [count] count默认为1
◎从集合中随机弹出元素 spop key --注意这个操作后,随机弹出的元素将被删除
◎获取所有元素 smembers key
◎多个集合的交集 sinter key [key ...]
◎多个集合并集 sunion key [key ...]
◎多个集合差集 sdiff key [key ...]
◎将交集结果保存 sinterstore destination key [key ...]
◎将并集结果保存 sunionstore destination key [key ...]
◎将差集结果保存 sdiffstore destination key [key ...]
◎intset(整数集合):元素都是整数且元素个数<512,减少内存使用;
◎hashtable(哈希表):不满足intset条件。
①典型就是标签,举例一个用户可能对娱乐、体育比较感兴趣,另一个可能对历史、新闻比较感兴趣,这些兴趣点就是标签,以此可以得到喜欢同一个标签的人,以及用户共同喜欢的标签,对于增强用户体验和用户粘度比较重要。
a 给用户添加标签
sadd user:1:tags tag1 tag2 tag3 tag5 tag7 tag8
sadd user:2:tags tag3 tag6 tag9 tag10 tag12 tag15
.....
sadd user:k:tags tag2 tag4 tag6 tag8 tag10 tag17
.....
b 给标签添加用户
sadd tag1:users user:1 user:3
sadd tag2:users user:1 user:3 user:5 user:8 user:12 user:k
.....
sadd tagk:users user:3 user:7 user:21 user:35
.....
c 删除用户下的标签
srem user:1:tags tag1 tag5
.....
d 删除标签下的用户
srem tag1:users user:1
srem tag5:users user:5 user:9 user:8 user:15 user:56
.....
注:c和d要放在一个事物里面执行
e 计算用户共同感兴趣的标签
sinter user:1:tags user:3:tags user:5:tags user:7:tags
②其他通用场景
spop/srandomember = random item (生成随机数,不如抽奖)
sadd + sinter = social graph(社交需求)
有序集合保留了集合不能有重复元素的特性,但元素可以排序,其为每个元素设置了一个分数作为排序依据,支持集合内的增删改查,还支持集合间交并差。
◎添加元素 zadd key score meneber [score meneber ...]
---redis3.2为zadd添加了nx/xx/ch/incr
---nx member必须不存在,用于添加
---xx member必须存在,用于更新
---ch 返回此次操作后元素和个数发生变化的个数
---incr 对score做增加
◎计算成员个数 zcard key
◎计算某个成员的分数 zscore key menber
◎计算成员排名 zrank key member
zrevrank key member
--zrank分数从低到高,zrevrank 反之;
--排名从0开始计算。
◎删除成员 zrem key menber [member ...]
◎增加成员个数 zincrby key increment member
◎返回指定排名范围的成员 zrange key start end [withscores]
zrevrange key start end [withscores]
◎返回指定分数范围的成员 zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key min max [withscores] [limit offset count]
◎返回指定分数范围成员个数 zcount key min max
◎删除指定排名内的升序元素 zremrangebyrank key start end
◎删除指定分数范围的成员 zremrangebyscore key min max
◎交集 zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
◎并集 zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
◎ziplist(压缩列表) :有序集合元素个数<512&&值都<64, 节省内存;
◎skiplist(跳跃表):不满足ziplist(压缩列表)时。
典型的就是排行榜系统。举例视频网站需要对用户上传的视频做排行榜,榜单的维度可以使多面的:按照时间、按照播放数量、按照获得的赞数。
a 添加用户赞数
zadd user:ranking:2018-09-18 666 zyf
若再次获赞
zincrby user:ranking:2018-09-18 1 zyf
b 取消用户的赞数
zrem user:ranking:2018-09-18 zyf
c 展示获取赞数最多的十个用户
zrevrangebyrank user:ranking:2018-09-18 0 9
d 展示用户信息以及用户分数
hgetall user:info:zyf
zscore user:ranking:2018-09-18 zyf
zrank user:ranking:2018-09-18 zyf