目录
[1. 更新系统包](#1. 更新系统包)
[2. 安装 Redis](#2. 安装 Redis)
[3. 启动 Redis 服务](#3. 启动 Redis 服务)
[5. 验证 Redis 运行状态](#5. 验证 Redis 运行状态)
[6. 测试 Redis 连接](#6. 测试 Redis 连接)
[修改 Redis 配置文件](#修改 Redis 配置文件)
[1. 定位配置文件](#1. 定位配置文件)
[2. 备份配置文件(重要!)](#2. 备份配置文件(重要!))
[3. 编辑配置文件](#3. 编辑配置文件)
[4. 常见配置项修改](#4. 常见配置项修改)
[(1) 允许远程访问(默认仅本地)](#(1) 允许远程访问(默认仅本地))
[(2) 设置访问密码](#(2) 设置访问密码)
[(3) 调整持久化策略](#(3) 调整持久化策略)
[(4) 修改默认端口](#(4) 修改默认端口)
[(5) 限制内存使用](#(5) 限制内存使用)
[5. 保存并退出编辑器](#5. 保存并退出编辑器)
[6. 重启 Redis 使配置生效](#6. 重启 Redis 使配置生效)
[7. 验证配置是否生效](#7. 验证配置是否生效)
[(1) 检查运行状态:](#(1) 检查运行状态:)
[(2) 测试密码登录:](#(2) 测试密码登录:)
[(3) 检查绑定地址和端口:](#(3) 检查绑定地址和端口:)
[连接 Redis 服务](#连接 Redis 服务)
[Watch 监控](#Watch 监控)
在ubuntu中下载redis
1. 更新系统包
sudo apt update
2. 安装 Redis
sudo apt install redis-server -y
3. 启动 Redis 服务
sudo systemctl start redis-server
4.设置开机自启
sudo systemctl enable redis-server
//(验证开机自启是否生效:
sudo systemctl is-enabled redis-server
若返回 enabled,表示开机自启已成功配置;
若返回 disabled,需重新执行 sudo systemctl enable redis-server 并检查配置文件路径。
)
5. 验证 Redis 运行状态
sudo systemctl status redis-server
//正常会显示 active (running)
6. 测试 Redis 连接
redis-cli ping
//若返回 PONG 表示 Redis 服务正常
修改 Redis 配置文件
1. 定位配置文件
Redis 的默认配置文件路径为:
/etc/redis/redis.conf
2. 备份配置文件**(重要!)**
sudo cp /etc/redis/redis.conf /etc/redis/redis.conf.bak
3. 编辑配置文件
使用 nano 编辑器(或其他编辑器如 vim):
sudo nano /etc/redis/redis.conf
4. 常见配置项修改
(1) 允许远程访问(默认仅本地)
# 找到 `bind` 行,修改为:
bind 0.0.0.0 # 允许所有 IP 访问
# 或指定特定 IP:
bind 127.0.0.1 192.168.1.100 # 允许本地和 192.168.1.100 访问
(2) 设置访问密码
# 找到 `# requirepass foobared`,取消注释并修改密码:
requirepass your_password
(3) 调整持久化策略
默认 RDB 快照配置(根据需求调整):
save 900 1 # 900 秒(15 分钟)内至少 1 个键被修改则保存
save 300 10 # 300 秒(5 分钟)内至少 10 个键被修改
save 60 10000 # 60 秒内至少 10000 个键被修改
(4) 修改默认端口
找到 `port 6379`,修改为其他端口(如 8888):port 8888
(5) 限制内存使用
# 设置最大内存(例如 2GB):
maxmemory 2gb
# 设置内存满时的淘汰策略:
maxmemory-policy allkeys-lru
5. 保存并退出编辑器
nano:按 Ctrl + O 保存 → 按 Ctrl + X 退出。
vim:按 Esc → 输入 :wq → 回车。
6. 重启 Redis 使配置生效
sudo systemctl restart redis-server
7. 验证配置是否生效
(1) 检查运行状态:
sudo systemctl status redis-server
#若状态为 active (running) 表示重启成功
(2) 测试密码登录:
redis-cli -a your_password
> ping # 应返回 PONG
(3) 检查绑定地址和端口:
ss -tuln | grep 6379
# 确认 Redis 监听端口和 IP
连接 Redis 服务
若不想每次手动认证,可在启动 redis-cli 时通过 -a 参数直接指定密码:
redis-cli -a your_password
# 进入 Redis 命令行后执行认证
127.0.0.1:6379> AUTH your_password
OK # 返回 OK 表示密码正确
十大数据类型
- String : 一个字符串value最多是512M,是二进制安全的字符串,支持序列化
- List :底层是双向链表,List最多可存40亿元素
- Hash:(哈希表)使用存对象,是键值对
- Set:(无序集合)不能有重复的
- ZSet:(有序集合)
- GEO:(地理空间)存储地理位置信息,计算2个位置距离
- HyperLogLog:(基数统计)用来做基数统计的,
- bitmap:(位图)由0和1状态表现二进制bit数组,可用于记录一周内是否打卡状态
- bitfield:(位域)一次性操作多个比特位域
- Stream:(流)主要用于消息队列,支持发布订阅
redis 命令手册https://redis.com.cn/commands.html
键(Key)命令
# 查
127.0.0.1:6379> keys * # 查看当前库里所有的key
exists key名 # 判断某个key是否存在, 1代表存在,0代表不存在
type key名 # 查看你的key是什么类型
expire key名 秒数 # 给key设置过期时间,单位(描述)
ttl key名 # 查看key还有多少秒过期,单位(秒) -1代表永不过期 -2 代表已过期
# 删除
del key名 # 删除指定的key数据
unlink key名 # 非阻塞删除,先keyspace元数据删除,没真正的删除会在后续异步中操作,不会阻塞的删除
# 对数据库的操作,redis默认是有16个数据库的,默认是0号库
move key名 dbindex [0-15] # 将当前数据库的key移动到指定的数据库中 例子:move key名 3 (把key移到3号库)
select dbindex [0-15] # 切换数据库[0-15],默认为0,例子:select 3 (切换到3号库)
dbsize # 查看当前数据库key的数量,相当于SQL的 select count(key)
flushdb # 清空当前库
flushall # 清空16个数据库,谨慎使用
# 批量删除 - 通过管道进行批量删除,"***" 代表 key前缀
redis-cli -a 密码 keys "***" | xargs redis-cli del
字符串(String)
# 设置值 20秒过期 ex代表以秒为单位设置 px代表以毫秒为单位设置
set key名 value值 ex 20
# 修改key的值,如果后面加了keepttl,代表保留设置前指定的过期时间,只改value值,过期时间不重置
set key名 value值 keepttl
# 获得对应的值
get key名
# 同时设置一个或多个键值对
MSET [key1] [value1] [key2] [value2] [key3] [value3]
# 同时获取多个key的值
MGET [key1] [key2] [key3]
# 同时设置一个或多个 key-value 对 必须保证key都不存在才能成功
MSETNX [key1] [value1] [key2] [value2]
# 这个相当于对value值进行截取
GETRANGE [key] 0 -1 # 获取这个key的值的全部
GETRANGE [key] 0 2 # 获取这个key的值索引0到索引2之间的值
# 获取字符串长度和内容相加
STRLEN [key] # 获取key对应的值的长度
APPEND [key] [vale] # 添加字符串内容
# 数值增减,value值一定是数字
INCR [key] # 递增数字 +1
INCRBY [key] [increment] # 增加指定的整数 +increment
DECR [key] # 递减数字 -1
DECRBY [key] [increment] # 减少指定的整数 -increment
# 分布式锁
setnx/setex [key] [过期时间] [value] # 设置带过期时间的key,动态设置,例子:setnx k1值 10 v1值
setnx [key] [value] # 只有在 key 不存在时设置 key 的值。
# 一般是两个命令连用,写成lua脚本连用,具体在Redis高级分布式锁中使用
# getset(先get再set)
getset [key] [value] # 给定 key 的值设为 value ,并返回 key 的旧值
列表(List)
单个key,多个value,一般用在栈、队列、消息队列等场景,底层是双端链表
lpush [key] [value] ... # 从(左边)放入元素 例:lpush key1 1 2 3 4
Rpush [key] [value] ... # 从(右边)放入元素
lrange [key] 0 -1 # 从左边开始遍历列表 只能从左边遍历
lpop [key] # 最左边的出栈 也就是lrange遍历的第一个,也就是删除掉
rpop [key] # 最右边的出栈 也就是lrange遍历的最后一个
lindex [key] [index] # 通过索引值获取值
llen [key] # 获得元素个数
lrem [key] [num] [value] # 从左往右删除 num个值为 value的值
lrem [key] 0 [value] # 从左往右删除所有值为value的值
ltrim [key] [开始] [结束] # 截取指定范围的值后再赋给[key],也就是删除这个区间外的值
RPOPLPUSH [key1] [key2] # 移除列表的最后一个元素,并将该元素添加到另一个列表的第一个并返回
lset [key] [index] [value] # 将key的第 index 个索引值改为value
linsert [key] before/after [value1] [value2] # 在list某个已有值的前后再添加具体
应用场景:
用户id收藏了文章1、文章2、文章3 ,命令:lpush likearticle:用户id 文章id1 文章id2 文章id3
查询用户最近收藏3条文章; lrange likearticle:用户id 0 3 (0到3条记录)
哈希(Hash)
目前基本不用,结构类似Map<String,Map<Object,Object>>,-->key<<key,value>>
hset user id 11 name z1 # 创建一个hash的key
hget user id # 获取key里其中一个值
hlen # 获取在某个key内的全部数量
hexists [key] [k1] # 看key中是否有k1这个键
hkeys [key] # 获取key里面的所有key
hvals [key] # 获取key里面的所有value
集合(Set)
SADD key member ... # 添加元素 例:sadd set1 1 2 3 3 4 ,**去的数据是1 2 3 4
SMEMBERS key # 遍历集合中所有元素
SISMEMBER key member # 判断元素是否在集合中
SREM key member ... # 删除元素
SCARD key # 获取集合长度
SRANDMEMBER key m # 从set集合里面随机取出m个 ,如果超过最大数量就全部取出 如果写的值是负数,比如-3 ,表示需要取出3个,但是可能会有重复值 不会删除
SPOP key m # 从集合中随即弹出一个元素 出一个删一个
SMOVE key1 key2 在key1里已存在的某个值 # 将key1的已存在的某个值赋给key2
# 集合运算
SDIFF keyA keyB # A - B 属于A但不属于B的元素构成的集合
SUNION keyA keyB # A U B 属于A或者属于B的元素合并后的
SINTER keyA keyB # A ∩ B 属于A同时属于B
SINTERCARD numkeys keyA keyB [LIMIT limit] # 不返回结果集,只返回结果的基数
应用场景:
-
微信抽奖
用户1参加抽奖,命令:sadd key 用户id 显示多少人参加,命令:SCARD key 进行抽奖,命令:SRANDMEMBER key 2 (随机抽2个人,但2人不删除,可还可以参与抽奖) 命令:spop key 3 (随机抽3人,会从集合中删除掉)
-
集合运算
sadd s1 1 2 3 4 sadd s2 3 4 5 6 SDIFF s1 s2 # 求差集 得出 1 2 SDIFF s2 s1 # 求差集 得出 5 6 SINTER s1 s2 # 求交集 得出 3 4
有序集合(Zset)
有序的集合,在set的基础上加了一个score分数值,根据分数值排序
ZADD key score member [ score member ] # 添加元素 例:zadd k1 60 王者 30 飞车 20 派对
ZRANGE key start stop [WITHSCORES] # 返回元素分数从小到大的顺序 返回索引从start到stop之间的所有元素例:ZRANGE k1 0 -1 (全部) 或 ZRANGE k1 0 -1 (全部) withscores (带分数值返回)
ZREVRANGE key 0 - 1 [WITHSCORES] # 反序
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] # 获取指定分数范围的元素(min,max) 不包含 limit是返回限制,返回多少个
ZSCORE key member # 获取元素的分数
ZCARD key # 获取集合中元素的数量
ZREM key 某score下对应的value值 # 删除元素
ZINCRBY key increment member # 增加某个元素的分数
ZCOUNT key min max # 获得指定分数范围内的元素个数
ZRANK key values值 # 获得下标值
ZREVRANK key values # 逆序获得下标值、
位图(bitmap)
由 0 和 1 表示的二进制位的 bit 数组
SETBIT key offset value # 将第offset的值设为value value只能是0或1 offset 从0开始
GETBIT key offset # 获得第offset位的值
STRLEN key # 得出占多少字节 超过8位后自己按照8位一组一byte再扩容
BITCOUNT key # 得出该key里面含有几个1
BITOP and destKey key1 key2 # 对一个或多个 key 求逻辑并,并将结果保存到 destkey
BITOP or destKey key1 key2 # 对一个或多个 key 求逻辑或,并将结果保存到 destkey
BITOP XOR destKey key1 key2 # 对一个或多个 key 求逻辑异或,并将结果保存到 destkey
BITOP NOT destKey key # 对key 求逻辑非,并将结果保存到 destkey
应用场景:
# 做打卡签到场景
# 第一天打开:setbit sign:用户id1:202201 0 1
# 第二天打开:setbit sign:用户id1:202202 1 1
# 第三天打开:setbit sign:用户id1:202203 2 1
# 第六天打开:setbit sign:用户id1:202203 5 1
# 查看第三天有没有来, getbit sign:用户id1:202203 2 # 得出结果是 0
# 查看统计这个月打开几次:bitcount sign:用户id1:202203 0 30 # 得出结果是4个数
基数统计(HyperLogLog)
它本身不会存储元素本身,统计某个网站的UV,某个文章的UA,UA是(独立访客,一般是客户端的IP)
pfadd hel 1 3 5 7 # 添加元素 ,然后统计个数是:4
pfadd he2 1 3 3 4 6 7 # 添加元素 ,然后统计个数是:5
pfcount hel # 打印he1个数 ,结果是 4
pfmerge he新 he1 he1 # 添加元素,多个元素
pfcount he新 # 打印he新个数 ,结果是 6
# 适合做统计个数,并不保留结果,添加元素,添加客户端iP
地理空间(Geospatial)
用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],只要我们确定一个点的经纬度就可以名取得他在地球的位置
geoadd key1 经度1 纬度1 "天安门" 经度2 纬度2 "天安门2" # 添加经纬度坐标
ZRANGE key1 0 -1 # 获取全部的value值
# 如果返回值,有中文乱码,解决:redis -cli -a 123456 -- raw (在外部,Linux命令行输入)
geopos key1 天安门 天安门2 # 返回经纬度
GEOHASH key1 天安门 天安门2 # 返回经纬度坐标的(base32编码)
GEODIST key1 天安门 故宫 km # 返回两个位置之间的距离,km是单位:千米 或 m:米
GEORADIUS 以给定的经纬度为中心, 返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素
# 例子:GEORADIUS key1 114.12 39.2 10 km withcoord withhash count 10 desc
# key (现在的经纬度) 10 (km或m) withcoord(会打印hash值)withhash(返回经纬度坐标)count 10(返回10条)
GEORADIUSBYMEMBER 它这个输入范围元素 例:GEORADIUS key1 天安门 10 km ...
事务
Redis是单线程架构,在执行事务内的指令,不可能执行其他客户端的请求处理;它在一组队列中,顺序的执行一系列指令;
特点:没有隔离性的概念、不保证原子性(可能一部分成功,一部分失败)、不能回滚、排他性(一个事务依次执行,不会被其他指令插入)
错误分为:编译型(代码有问题,命令有错,事务所有命令都不会执行);运行时异常(比如1/0),如果事务中存在语法性错误,那么执行命令时,其他命令是可以执行的,错误命令抛出异常。
# 开启事务 MULTI
# 执行事务 EXEC
# 放弃事务 DISCARD
# 案例
MULTI # 开启事务
set key1 11 # 添加数据
set key2 22
EXEC # 提交事务
DISCARD #取消事务
(nil)
# 1 如果中间有语法错误,会直接返回结果,全部指令逻辑都不会执行
# 2 如果中间有语法没错,但没有语法错误,指的是get 不存在的值,事务会有效,会执行有效的指令
Watch 监控
相当于Redis的乐观锁,一旦执行了EXEC,监控也就会取消.
watch
# 开始进行监控,先监控再开启事务,保证两key变动在同一事务内,如果有其他人先修改了k1,会返回nil,执行失败,比较并交换
# 案例:
get k1
watch k1
MULTI # 提交事务
set k1 新值1 # 修改数据
set k2 新值2
get k1
get k2
EXEC # 提交事务
unwatch
# 放弃监控
# 案例:
get k1
watch k1
get k2
unwatch
测试多线程修改值,使用watch可以当作redis的乐观锁操作
127.0.0.1:6379> watch money # 监视money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec # 执行之前,另外一个线程修改了我们的值,就会导致事务提交失败
(nil)