redis安装、启动、连接、以及redis五种数据类型及命令
redis介绍安装和配置典型应用场景
介绍
- 开源,早起版本2w3千行代码,c语言写的
- 基于键值对的存储系统,字典形式
- 多种数据结构:字符串、hash、列表、集合、有序集合
- 高性能,功能丰富
redis特性
快:10w的ops(每秒10w读写),数据存在内存中,c语言实现,单线程模型
持久化:rdb和aof,两种持久化方式
- rdb:
redis database
,rdb持久化是把当前进程数据生成快照保存到磁盘上的过程,由于是某一时刻的快照,那么快照中的值要早于或者等于内存中的值 - redis是写后日志,redis先执行命令,把数据写入内存,然后才记录日志。日志里记录的是redis收到的每一条命令
严格意义上来说,redis服务提供四种持久化存储方案:RDB,AOF,虚拟内存(VM),和DISKSTORE.
数据结构
- 5大数据结构:字符串、列表、hash、集合、有序集合
- BitMaps位图:布隆过滤器,本质是字符串
- HyperLogLog:超小内存唯一值计数,12kb;本质就是字符串
- GEO:地理信息定位,本质就是有序集合
功能丰富:发布订阅(消息) LUA脚本,事务(pipline)
简单:源码代码几万行,不依赖外部库
主从复制:主服务器和从服务器,主服务器可以同步到从服务器中
高可用和分布式:
- 2.8版本以后使用redis-sentinel支持高可用
- 3.0版本以后支持分布式
redis的单线程模型
主要是指redis的网络io和键值对的读写是由一个线程来完成的,这也是redis对外提供兼职存储服务的主要流程。
但是redis的其他功能,比如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的。所以,严格上来说,redis并不是单线程的。
redis典型使用场景
- 缓存系统:使用最广泛的就是缓存
- 计数器:网站访问量,转发量,评论数(文章转发,商品销量,单线程模型,不会出现并发问题)
- 消息队列:发布订阅,阻塞队列实现(简单的分布式,blpop:阻塞队列,生产者消费者)
- 排行榜:有序集合(阅读排行,点赞排行,推荐(销量高的,推荐))
- 社交网络:集合,很多特效跟社交网络匹配,粉丝数,关注数
- 实时系统:垃圾邮件处理系统,布隆过滤器
- 地理位置信息:GEO,附近的人。。。
redis的linux安装和卸载
下载
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
解压
tar -xzf redis-5.0.7.tar.gz
建立软连接
ln -s redis-5.0.7 redis
编译安装
cd redis
make && make install
查看
redis-server redis服务器
redis-cli redis性能测试工具
redis-benchmark redis性能测试工具
redis-check-aof aof文件修复工具
redis-check-dump rdb文件检查工具
redis-sentinel sentinel服务器,哨兵
卸载redis
查看redis进程
ps aux|grep redis
kill掉进程
kill 进程id
删除redis对应的文件
rm -f /usr/local/redis/bin/redis*
rm -f /usr/local/bin/redis*
删除对应的文件
rm -rf redis
三种启动方式
最简启动
redis-server
ps -aux|grep redis #查看进程
netstat -antpl|grep redis #查看端口
netstat -nlp |grep 6379
redis-cli -h ip -p port ping #命令查看
动态参数启动
redis-serve --port 6380 #启动,监听6380端口
配置文件启动
查看一下默认注释,把#
和空格去掉
cat redis.conf |grep -v "#" |grep -v "^$"
重定向到另一个文件
cat redis.conf|grep -v "#" |grep -v "^$" >redis-6382.conf
- daemonize yes:是否以守护进程启动
- pidfile /var/run/redis.pid: 进程号的位置
- port 6379:端口号
- dir /opt/soft/redis/data:工作目录
- logfile 6379.log:日志位置
在redis目录下新建data目录,用来存放数据
启动redis
redis-server /root/redis/redis.conf
查看进程
ps -ef |grep redis-server |grep 6379
查看日志
cd data
cat 9379.log
客户端连接(命令)
redis-cli -h 地址 -p 端口
查看所有配置
config get * # 107对
port
daemonize
logfile
dbfilename
requirepass # 设置密码
maxmemory # 最大占用内存,0 不限制
databases #16 个库
maxclients
appendonly # 持久化
dir
slaveof # 复制谁,如果是从库,这个地方要写主库
bind
修改配置(直接改文件)
修改配置(客户端直接修改),临时改,当前进程不停,生效,重启就没了
config set maxmemory 128m
config get maxmemory
config set requirepass 123456
config rewrite # 永久生效,同步到配置文件中
直接客户端链接,修改配置信息,写到配置文件中
如果以root用户启动redis,config rewrite功能,会导致黑客提权,直接登录到系统中,放挖矿病毒
避免措施
- 端口跑在别的上,不是6379
- redis密码设置尽量复制
- 不用root用户启动redis,启动redis的用户,不允许登录系统ssh链接
redis返回值
状态回复:ping---》PONG
错误回复:hget hello field ---》(error)WRONGTYPE Operation against
整数回复:incr hello---》(integer) 1
字符串回复:get hello---》"world"
多行字符串回复:mget hello foo---》"world" "bar"
redis通用命令
补充
大O表示法,衡量算法优劣的标准
- 时间复杂度
- 空间复杂度
O(1) 最好的,只需要一次就能拿到结果
O(log n) n的一半
O(n) 循环n次
O(n2) 两层for循环
1-keys
打印出所有key
keys *
打印出所有以he开头的key
keys he*
打印出所有以he开头,第三个字母是h到l的范围
keys he[h-l]
三位长度,以he开头,?表示任意一位
keys he?
keys命令一般不在生产环境中使用,生产环境key很多,时间复杂度为O(n),用scan命令
2-dbsize
:计算key的总数
dbsize:redis内置了计数器,插入删除值该计数器会更改,所以可以在生产环境使用,时间复杂度为O(1)
3-exists key:时间复杂度为o(1)
# 设置a
set a b
# 查看a是否存在
exists a
4-del key:时间复杂度为o(1)
删除成功返回1,key不存在返回0
5-expire key seconds 时间复杂度为O(1)
expire name 3 # 设置3秒过期
ttl name # 查看name还有多长时间过期
persist name # 去掉name的过期时间
6-type key 时间复杂度O(1)
type name
:查看name类型,返回string
其他
info命令:内存,cpu,主从相关,redis监控
client list:正在连接的会话
client kill ip:端口
dbsize:总共有多少个key
flushall:清空所有
flushdb:只清空当前库
select 数字:选择某个库,总共16个库
monitor:记录操作日志,阻塞住
redis字符串命令
基本使用get,set,del
get name
set name xunfei
del name
其他使用incr,decr,incrby,decrby
incr age # 对age这个key的value值自增1
decr age # 对age这个key的value值自减1
incrby age 10 # 对age这个key的value值增加10
incrby age 10 # 对age这个key的value值减10
应用:
- 统计网站访问量(单线程无竞争,天然适合做计数器)
- 分布式id生成(多个机器同时并发着生成,不会重复)
set,setnx,setxx
set name xunfei # 不管key 是否存在,都设置
setnx name xunfei # key不存在时才设置(新增操作)
set name xf nx # 同上
set name xf xx # key存在,才设置(更新操作)
mget mset
mget key1 key2 key3 # 批量获取key1,key2。 时间复杂度为o(n)
mset key1 value1 key2 value2 key3 value3 3 批量设置时间复杂度O(n)
n次get和mget的区别
- n次get时间=n次命令时间和n次网络时间
- mget时间=1次网络时间+n次命令时间
其他:getset,append,strlen
getset name xf # 设置新值并返回旧值,时间复杂度o(1)
append name xf # 将value追加到旧的value,时间复杂度o(1)
strlen name # 计算字符串长度(注意中文),时间复杂度o(1)
其他:incrybyfloat,getrange,setrange
increbyfloat age 3.5 # 为age自增3.5,传负值表示自减,时间复杂度为o(1)
getrange key start end # 获取字符串制定下标所有的值,时间复杂度为O(1)
setrange key index value # 从指定index开始设置value值,时间复杂度为O(1)
作用:缓存,计数器
redis列表命令
插入操作
rpush 从右侧插入
rpush key value1 value2 ...valuen # 时间复杂度为o(1~n)
lpush从左侧插入
linsert
linsert key before|after value newValue # 从元素value的前或后插入newValue,时间复杂度o(n),需要遍历列表
linsert myname before xunfei jason # 在myname列表中xunfei前面插入jason
linsert listkey before b java
linsert listkey after b php
删除操作
lpop key # 从列表左侧弹出一个item 时间复杂度为o(1)
rpop key # 从列表右侧弹出一个item 时间复杂度为o(1)
lrem key count value
# 根据count值,从列表中删除所有value相同的项,时间复杂度o(n)
- count>0,从左到右,删除最多count个value相等的项
- count<0,从右向左,删除最多Math.abs(count)个value相等的项
- count=0,删除所有value相等的项
lrem key 0 a # 删除列表中所有值a
lrem key -1 c # 从右侧删除1个c
ltrim key start end # 按照索引范围修剪列表 o(n)
ltrim key 1 2 # 只保留下表1-2的元素
查询操作
lrange key start end # 包含end获取列表指定索引范围所有item o(n)
lrange key 0 2
lrange key 1 -1 # 获取第一个位置到倒数第一个位置的元素
lindex key index # 获取列表指定索引的item o(n)
lindex key 0
lindex key -1
llen key # 获取列表长度
修改操作
lset key timeout # lpop的阻塞版,timeout是阻塞超时时间,timeout=0为拥有不阻塞o(1)
lset key timeout # rpop的阻塞版,timeout是阻塞超时时间,timeout=0为拥有不阻塞o(1)
要实现栈的功能
lpush+lpop
实现队列功能
lpush+rpop
固定大小的列表
lpush+ltrim
消息队列
lpush+brpop
作用,功能
实现timeLine功能,时间轴,微博关注的人,按时间轴排列,在列表中放入关主任的微博即可
redis字典命令
1 hget,hset,hdel
hget key field # 获取hash key对应的field的value,时间复杂度为o(1)
hset key field value # 设置hash key对应的field的value值,时间复杂度为o(1)
hdel key field # 删除hash key 对应的field的值,时间复杂度为o(1)
# 测试
hset user:1:info age 23
hget user:1:info age
hset user:1:info name xunfei
hgetall user:1:info
hdel user:1:info age
2 hexists,hlen
hexists key field # 判断hash key是否存在field时间复杂度为o(1)
hlen key # 获取hash key field的数量,时间复杂度为o(1)
hexists user:1:info name
hlen user:1:info # 返回数量
3 hmget,hmset
hmget key field1 field2 ...fieldn # 批量获取hash key的一批field对应的值,时间复杂度为o(1)
hmset key field1 value1 field2 value2 # 批量设置hash key的一批field value,时间复杂度为o(1)
4 hgetall,hvals,hkeys
hgetall key # 返回hash key 对应的所有field和value,时间复杂度为o(n)
hvals key # 返回hash key对应的所有field的value,时间复杂度为o(n)
hkeys key # 返回hash key对应的所有field,时间复杂度为o(n)
# 小心使用getall
# 计算网站每个用户主页的访问量
hincrby user:1:info pageview count
5 其他操作 hsetnx,hincrby,hincrbyfloat
hsetnx key field value # 设置hash key对应field的value(如果field已存在,则失败),时间复杂度o(1)
hincrby key field intCounter # hash key对应的field的value自增intCounter,时间复杂度为o(1)
hincrbyfloat key field floatCounter # hincrby 浮点数,时间复杂度o(1)
作用
- 缓存,缓存用户信息,数据
- 计数器
redis集合
无序,无重复,集合间操作(交叉并补)
常用api
sadd key element # 向集合key添加element(如果element存在,添加失败) o(1)
srem key element # 从集合中的element移除掉,o(1)
scard key # 计算集合大小
sismember key element # 判断element是否在集合中
srandmember key count # 从集合中随机取出count个元素,不会破坏集合中的元素
spop key # 从集合中随机弹出一个元素
smembers key # 获取集合中的所有元素,无序,小心使用,会阻塞
sdiff user:1:follow user:2:follow # 计算user:1:follow和user:2:follow的差集
sinter user:1:follow user:2:follow # 计算user:1:follow和user:2:follow的交集
sunion user:1:follow user:2:follow # 计算user:1:follow和user:2:follow的并集
sdiff|sinter|suion +store destkey... # 将差集,交集,并集结果保存在destkey集合中
作用
- 抽奖系统:通过spop来弹出用户的id,活动取消,直接删除
- 点赞,点踩,喜欢等,用户如果点了赞,就把用户id放到该条记录的集合中
- 标签:给用户、文章等添加标签,
sadd user:1:tags 标签1 标签2 标签3
- 给标签添加用户,关注该标签的人有哪些
- 共同好友:集合间的操作
redis有序集合
不重复,有个分值字段,保证集合有顺序
操作
zadd key score element # score可以重复,可以多个同时添加,element不能重复 o(logn)
zrem key element # 删除元素,可以多个同时删除
zscore key element # 获取元素的分数
zincreby key incresocre element # 增加或减少元素的分数
zcard key # 返回元素总个数
zrank key element # 返回element元素的排名(从小到大排)
zrange key 0 -1 # 返回排名,不带分数,o(log(n)+m) n是元素个数,m是获取的值
zrange player:rank 0 -1 withsscores # 返回排名,带分数
zrangebyscore key minScore maxScore #返回指定分数范围内的升序元素 o(log(n)+m) n是元素个数,m是要获取的值
zrangebyscore user:1:ranking 90 210 withscores #获取90分到210分的元素
zcount key minScore maxScore #返回有序集合内在指定分数范围内的个数 o(log(n)+m)
zremrangebyrank key start end #删除指定排名内的升序元素 o(log(n)+m)
zremrangebyrank user:1:rangking 1 2 #删除升序排名中1到2的元素
zremrangebyscore key minScore maxScore #删除指定分数内的升序元素 o(log(n)+m)
zremrangebyscore user:1:ranking 90 210 #删除分数90到210之间的元素
zrevrank #从高到低排序
zrevrange #从高到低排序取一定范围
zrevrangebyscore #返回指定分数范围内的降序元素
zinterstore #对两个有序集合交集
zunionstore #对两个有序集合求并集
作用
排行榜:音乐排行榜,销售磅,关注磅,游戏排行榜