Redis笔记
安装
官方推荐使用 Linux 去开发使用!
window
下载地址:https://github.com/tporadowski/redis/releases
下载 Redis-x64-xxx.zip压缩包 解压为 redis
在 redis 目录下,打开 CMD 输入 或者双击运行 redis-server.exe
redis-server.exe redis.windows.conf
在打开一个输入
redis-cli.exe -h 127.0.0.1 -p 6379
即可连接
Linux
redis-6.0.8.tar.gz
# wget http://download.redis.io/releases/redis-6.0.8.tar.gz
# tar xzf redis-6.0.8.tar.gz
# cd redis-6.0.8
# 安装gcc-c++ 编译
yum instatll gcc-c++
# make
执行完 make 命令后,redis-6.0.8 的 src 目录下会出现编译后的 redis 服务程序 redis-server,还有用于测试的客户端程序 redis-cli
下面启动 redis 服务
# cd src
# ./redis-server
注意这种方式启动 redis 使用的是默认配置。也可以通过启动参数告诉 redis 使用指定配置文件使用下面命令启动。
# cd src
# ./redis-server ../redis.conf
redis 默认安装路径 /usr/local/bin
Docker
拉取镜像
docker pull redis
启动 Redis
docker run -d -v $PWD/data:/data --name redis -p 6379:6379 redis redis-server --requirepass "123456" --appendonly yes
启动命令说明:
$PWD/data:/data
: 映射 redis 的 data 目录到当前目录下的 data 目录--requirepass
: 是设置 redis 的密码--appendonly yes
: 启用持久化存储
例如:
docker run -d -v /home/app/redis/data:/data --name redis -p 6379:6379 redis redis-server --requirepass "123456" --appendonly yes
如果需要使用配置文件,则需要做个文件映射;注意所在目录下必须要有 redis.conf 这个文件,否则将启动失败。
docker run -d -v /home/app/redis/data:/data -v /home/app/redis/conf:/usr/local/etc/redis --name redis -p 6379:6379 redis redis-server /usr/local/etc/redis/redis.conf
redis 的这个配置文件可以到官方的这个地址上去获取 http://download.redis.io/redis-stable
更多: Docker 上安装 Redis
基本命令
Redis 不区分大小写 一般推荐大写(与 Mysql 一样)
set key value
get key
keys * # 查看所有key
EXISTS key # 判断key 是否存在
type key # 查看key的value类型
EXPIRE key second # 设置key的过期时间,单位是秒
ttl key # 查看当前key 的剩余时间
五大数据类型
Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 zset(sorted set:有序集合)。
String
APPEND key '123' # 给key 后面追加字符串123 如果key不存在 则为set 返回字符串长度
STRLEN key # 获取字符串长度
incr key # 自增1
decr key # 自减1
INCRBY key 10 # 递增10 指定增量
DECRBY key 10 # 递减10
GETRANGE key 0 3 # 截取字符串 0-3 包括3
GETRANGE key 0 -1 # 截取所有字符串
SETRANGE key 1 xxx # 替换指定位置的字符串
###########################################################################
setex (set with expire) # 设置过期时间
setnx (set if not exist) # 不存在在设置 (分布式锁中会常常使用)
setex key3 30 'hello' # 设置key3的为hello,30秒后过期
###########################################################################
mset mget msetex # 批量设置与批量获取
mset k1 v1 k2 v2 k3 v3
msetex k1 v1 k4 v4 # 原子性的操作 要么一起成功 要么一起失败
getset key value # 先取后设置 不存在则返回nil 如果存在,则获取,并赋为新值
############################################################################
# 对象
set user:1 {name:kuizuo,age:20} # 设置user为一个对象
# or
set user:1:name kuizuo
# user:{id}:{filed} value
get user:1
# or
get user:1:name
String 类似的使用场景: value 除了是字符串还可以是数字 或者对象
List
redis 里 List 可以充当栈,队列,阻塞队列
所有 list 命令用 l 开头
LPUSH list value # 将value 将一个值或多个值插入列表头部(左)
RPUSH list value # 将value 将一个值或多个值插入列表底部(右)
LRANGE list 0 -1 # 获取所有list元素
LPOP list # 移除list的第一个元素(左)
RPOP list # 移除list的最后一个元素(右)
Lindex list 1 # 通过下标获取list中的某一个值
Lset list 0 item # 如果不存在列表 去更新就会报错
Llen list # 取列表的长度
Lrem list 1 one # 移除指定的值 例:移除一个为one的
Ltrim list 1 2 # 截取1-2 包括2
Linsert list before "world" "new" # 在world 前面插入new 后面则用after
rpoplpush list1 list2 # 移除列表最后一个元素,将他移动到新的列表
列表实际上就是一个链表
可以实现消息队列 (Lpush Rpop),栈(Lpush Lpop)
Set
set 中的值是无法重复的,无序不重复集合
set 命令用 s 开头
sadd myset "hello" # set集合中添加元素
scard myset # 获取set集合中的内容元素个数
smembers myset # 查看指定set的所有值
sismember myset hello # 判断某一个值是不是在set集合中
SRANDMEMBER myset # 随机抽选出一个元素
SRANDMEMBER myset 2 # 随机抽选出指定个数元素
#####################################################################
# 获取set中的差集
SDIFF set1 set2
# 获取set中的交集
SINTER set1 set2
# 获取set中的并集
SUNION set1 set2
例如:共同好友就可以使用 set 交集来实现
Hash
Map 集合,key-map(key-value)
set 命令用 h 开头
hset myhash field1 kuizuo
hget myhash field1
hgetall myhash
hdel myhash
hlen myhash # 获取hash表的字段数量
HEXISTS myhash field1 # 判断hash中 指定字段是否存在
Hkeys myhash # 只获得所有field
Hvals myhash # 只获得所有value
hash 可变更数据 比如 user 信息,更适合对象的存储
Zset
有序集合,在 set 的基础上增加了一个值 score
zset 命令用 z 开头
zadd myset 1 one
zadd myset 2 two 3 three
# ZRANGEBYSCORE key min max 一定要从小到大
ZRANGEBYSCORE myset -inf +inf # 根据score排序
ZREVERANGE myset 0 -1 # 从大到小进行排序!
Zrem myset item # 移除有序集合中的指定元素
Zcard myset # 获取有序集合中元素的个数
案例:set 排序 班级成绩表,工资表排序
普通消息 1 重要消息 2 带权重进行判断
排行榜应用实现,取 TOP N
三种特殊数据类型
geospatial
地址位置,geospatial 命令用 geo 开头
GEO 底层的实现原理就是 Zset,所以可以使用 Zset 命令来操作 Geo!
应用: 推算地理位置的信息,两地之间的距离,方圆几里的人
# 规则: 两极无法直接添加,一般都是直接下载城市数据,直接通过程序一次性读入
# 参数: key (经度,纬度、名称) 切记不可反! 经纬度
# 有效经度-180度到180度 有效纬度-85.05112878到85.05112878
GEOADD china:city 116.40 39.90 beijin # 设置北京的经纬度
GEOPOS china:city beijing # 获取北京的经纬度
GEODIST china:city beijing shanghai unit # 获取两地之间的距离 默认单位m
GEORADIS china:city 110 30 1000 km # 以110,30 这个点范围1000km的 地理位置
GEORADIS china:city 110 30 500 km withdist withcoord count 10 # 以110,30 这个点范围500km的 获取10个 带直线距离和经纬度
GEORADIUSBYMEMBER chaina:city beijing 1000m # 以北京周围1000km的 地理位置
GEOHASH china:city beijing # 将二维的地址位置转为一位11位字符串,如果两个字符串越接近,则距离越近
ZRANGE chaina:city 0 -1 # 查看地图中全部元素
ZREM chaina:city beijing # 移除指定元素
Hyperloglog
Redis Hyperloglog 基数统计的算法
基数(不重复的元素),会有误差!0.81 的错误率,但 使用场景是可以接受的
统计网页的 UV (一个人访问一个网站多次,但是还是算作一个人),传统的方式,用 set 保存用户的 id,然后统计 set 中的元素数量来作为标准判断。
Hyperloglog 命令 使用 PF 开头
PFadd mykey1 a b c d e f g h i j
PFadd mykey2 i j k l m n o
PFMERGE mykey3 mykey1 mykey2 # 获取并集 并生成新的组
PFCOUNT mykey # 获取元素的数量
允许容错,一定可以使用 Hyperloglog
不允许容错,就使用 set 与自己的数据类型即可
Bitmaps
位存储
统计用户信息,活跃,不活跃;登录,不登录,打卡;两个状态的都可以使用 Bitmaps
Bitmaps 位图,数据结构,都是操作二进制为来进行记录,就只有 0 和 1 两个状态!
# 记录周一到周日的打卡
setbit sign 0 1
setbit sign 1 1
setbit sign 2 1
setbit sign 3 1
setbit sign 4 1
setbit sign 5 0
setbit sign 6 0
# 查看某一天是否有打开
getbit sign 3
# 统计打卡的天数
bitcount sign
事务
Redis 单条命令式保存原子性的,但是事务不保证原子性!
Redis 事务本质: 一组命令的集合!一个事务中的所有命令都会被序列化,会安卓顺序执行
一次性、顺序性、排他性!执行一些列的命令!
Redis 事务没有隔离级别的概念!
所有命令在事务中并没有直接呗执行!而只有发起执行命令的时候才会执行!Exec
- 开始事务(multi)
- 命令入队(...)
- 执行事务(exec)
multi
set k1 v1
set k2 v2
get k1
exec # 执行事务
DISCARD # 取消事务 事务队列中的命令都不会被执行
# 代码有问题,命令有错,事务中所有命令都不会被执行
# 运行中异常,执行其他命令正常,错误命令抛出异常
监控 Watch
悲观锁:很悲观,认为什么时候都会出问题,无论做什么都会加锁
乐观锁:很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候判断一下,在此期间是否有人修改过该数据
set money 100
set out 0
watch money
multi
DECRBY money 20
InCRBY money 20
# 如果这时用户充钱了 那么exec就无法执行
exec
# 解除监控,并重新监控最新的值
unwatch money
watch money
Redis.conf
配置文件 unit 单位对大小写不敏感
网络
bind 127.0.0.1 # 绑定的IP
protected-mode yes # 保护模式
port 6379 # 端口设置
GENERAL 通用
daemonize yes # 以守护进程方式的运行,默认是no,需自己开启yes
pidfile /var/run/redis_6379.pid # 以后台方式运行,就需要指定一个pid文件
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
logfile # 日志文件位置名
database 16 # 数据库数量 默认16个
alaways-show-logo yes # 是否总是显示LOGO
快照
持久化,在规定的时间内,执行了多少次操作,则会持久化到文件 .rdb .aof
stop-writes-on-bgsave-error yessave 900 1 # 在900s内,如果至少有一个key修改 则持久化操作
save 300 10 # 在300s内,如果至少有10个key进行修改 则持久化操作
save 60 10000
stop-writes-on-bgsave-error yes # 持久化如果出错 是否继续工作
rdbcompression yes # 是否压缩rdb文件,会消耗一些cpu资源
rdbchecksum yes # 保存rdb文件的时候,是否效验
dir ./ # rdb保存的目录
dbfilename dump.rdb # 保存的文件名
REPLICATION 主从复制
slaveof <masterip> <masterport> # 设置主机的端口和ip
SECURITY 密码
requirepass 密码
config get requirepass
config set requirepass "123456"
auth 123456
CLIENTS 客户端
maxclients 10000 # 默认客户端连接数
maxmemory <bytes> # redis 配置最大的内存容量
maxmemory-policy noeviction # 内存达到上限后的处理策略 # 移除一些过期的key
noeviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。(默认值)
allkeys-lru: 所有key通用; 优先删除最近最少使用(less recently used ,LRU) 的 key。
volatile-lru: 只限于设置了 expire 的部分; 优先删除最近最少使用(less recently used ,LRU) 的 key。
allkeys-random: 所有key通用; 随机删除一部分 key。
volatile-random: 只限于设置了 expire 的部分; 随机删除一部分 key。
volatile-ttl: 只限于设置了 expire 的部分; 优先删除剩余时间(time to live,TTL) 短的key。
APPEND ONLY MODE aof 配置
appendonly no # 默认不开启aof模式,默认使用rdb方式持久化,在大部分情况,rdb够用
appendfilename "appendonly.aof" # 持久化文件名
# appendfsync always # 每次修改都会 sync 消耗性能
appendfsync everysec # 美妙执行一次 sync,可能会丢失这1s的数据!
# appendfsync no # 不执行sync,这个时候操作系统自己同步数据,速度最快