redis 事务 持久化 主从架构
事务表示一组动作, 要么全部执行, 要么全部不执行。
ACID :保证执行多个指令的时候,要么都执行,要么都不执行,要么都成功,要么都没有成功 这个是数据库的事务
特点:原子性(Atomicity) 一致性(Consistency) 隔离性(Isolation) 持久性(Durability)
但是redis事务的特点是:提交--没有回滚,提交就提交了 ,成功或者不成功,只会返回一个结果
redis:
- Multi:标记事务的开始;
- Exec:执行事务的commands队列;
- Discard:结束事务,并清除commands队列;
redis里面使用普通事务,没有锁===
建议:如果要使用redis的事务,则需要和Watch方法一起使用,而且最好,监听的这些字段都包含在所有的key里面。。 小菜鸟玩事务,大神搞lua
public class TransAction { public static void Show() { try { //事务模式 using (RedisClient client = new RedisClient("127.0.0.1", 6379)) { //删除当前数据库中的所有Key 默认删除的是db0 client.FlushDb(); //删除所有数据库中的key client.FlushAll(); client.Set("a", "1"); client.Set("b", "1"); client.Set("c", "1"); ////获取当前这三个key的版本号 实现事务 client.Watch("a","b","c");//这里需要监听所有的key //client.Watch("c");//如果单独监听一个了,指定处理对应key上的事务 using (var trans = client.CreateTransaction()) { trans.QueueCommand(p => p.Set("a", "3")); trans.QueueCommand(p => p.Set("b", "3")); trans.QueueCommand(p => p.Set("c", "3")); var flag = trans.Commit(); Console.WriteLine(flag); } //根据key取出值,返回string Console.WriteLine(client.Get<string>("a") + ":" + client.Get<string> ("b") + ":" + client.Get<string> ("c")); Console.ReadLine(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadLine(); } }
·Lua脚本在Redis中是原子执行的, 执行过程中间不会插入其他命令。 ·Lua脚本可以帮助开发和运维人员创造出自己定制的命令, 并可以将这些命令常驻在Redis内存中, 实现复用的效果。 ·Lua脚本可以将多条命令一次性打包, 有效地减少网络开销。
public class LuaTest { public static void Show() { using (var client = new RedisClient("192.168.1.211", 6379)) { //Console.WriteLine(client.ExecLuaAsString(@"return redis.call('get','name')")); //库存 //Console.WriteLine(client.ExecLuaAsString(@"redis.call('set','number','10')")); var lua = @"local count = redis.call('get',KEYS[1]) if(tonumber(count)>=0) then redis.call('INCR',ARGV[1]) return redis.call('DECR',KEYS[1]) else return -1 end"; Console.WriteLine(client.ExecLuaAsString(lua, keys: new[] { "number" }, args: new[] { "ordercount" })); } } }
C#限流的例子
### 限流lua代码如下 local times = redis.call('incr',KEYS[1]) if times == 1 then redis.call('expire',KEYS[1], ARGV[1]) end if times > tonumber(ARGV[2]) then return 0 end return 1
/// <summary> /// 滑窗式限流 利用redis的Zset类型 /// </summary> /// <returns></returns> public bool LimitFlow() { DateTime currentTime = DateTime.Now; using (IRedisClient client = redisService.GetRedisClient()) { // 判断是否存在响应的key if (client.ContainsKey("服务名称")) { //获取前一秒和当前秒时间类的集合总数量 //此数量表示的就是请求数量 int count = client.GetRangeFromSortedSetByLowestScore("服务名称", currentTime.AddSeconds(-1).ToFileTimeUtc(), currentTime.ToFileTimeUtc()).Count; // 8表示的是限流的数量 //如果请求数量大于限流数量,则返回false,可以拒绝请求 if (count != null && count >8) { return false; } } //如果是第一次获取请求数量 //或者满足限流限制,则返回true,然后给Zset中添加一次请求数量,分数就是当前的时间戳 client.AddItemToSortedSet("服务名称", Guid.NewGuid().ToString(), currentTime.ToFileTimeUtc()); return true; } }
持久化
快照的方式(RDB)---每次都去抓拍一下全面貌 每次都全量备份
文件追加方式(AOF)--在之前的基础上追加
RDB机制:
RDB其实就是把数据以快照的形式保存在磁盘上。什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。
既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,是实现这个过程。对于RDB来说,提供了三种机制:save、bgsave、自动化。我们分别来看一下
查看默认配置命令 config get save :
指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
Redis 默认配置文件中提供了三个条件:
save 900 1
save 300 10
save 60 10000
分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改以及 60 秒内有 10000 个更改。
手动备份策略:
1.save: 阻塞线程--- 因为执行这个指令的线程就是redis里面唯一的那个执行指令的线程-
当你备份大量的数据的时候,如果耗时比较长,则当有其他客户端发送指令的时候,会卡主
2.bgsave: 单独的线程,后台专门有一个线程去实现备份。
这个后台的就是专门来根据我们的配置文件里策略然后去备份数据文件
底层原理: 有一个定时器,就是不停的计算我们阈值。每一次bgsave之后,要把计数器清0===
优势:备份缓慢,但是重启加载数据性能比较快。。。
文件追加方式(AOF):
查看aof是否开启命令 config get appendonly ,默认是没开启的
打开 redis.conf 修改以下参数:
appendonly yes (默认no,关闭)表示是否开启AOF持久化:
持久化的文件名为:appendonly.aof
AOF持久化策略(默认每秒):
appendfsync always (同步持久化,每次发生数据变更会被立即记录到磁盘,性能差但数据完整性比较好) 只要有读写就会执行同步
appendfsync everysec (异步操作,每秒记录,如果一秒钟内宕机,有数据丢失) 1s钟的周期 一般转字这一种
appendfsync no (将缓存回写的策略交给系统,linux 默认是30秒将缓冲区的数据回写硬盘的)这种操作最不可靠
日志追加:基本都是顺序读写//本身要比我们操作关系型数据库要快(mysql==)
优点是:文件可读行高,每次都是追加修改的东西,备份比较快,但是当服务重启的时候,加载数据的时候比较慢 上面是快照现在不是了----
如果rdb和aof都开启了,则默认首先加载aof文件,为了保证数据的尽可能完整性。
aof 重写问题:当数据文件到达一个阈值的时候,,我们的文件会继续重写变成一个小文件。(当AOF文件的大小超过了配置所设置的阙值时,Redis就会启动AOF文件压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof)
两者的优缺点:
rdb:备份慢,启动快
aof:备份快,启动慢
redis..4X 版本之后,混合模式---(也就是把两个可以混合使用) 混合模式【备份,启动快】 : 备份的时候,我通过aof备份,我还原的时候根据rdb..
aof--文件重写的问题---到数据大的时候,
当我们进行aof操作的时候,把aof文件变成rdb,然后之后的操作直接取做日志追加。。
默认的情况下,你要你开启了aof则,混合默认自动打开 配置文件中 : aof-use-rdb-preamble yes
混合模式的文件--包含aof和rdb; aof打开的同时混合默认打开,如何手动调用呢 使用命令bgrewriteaof
情况分析:
如果要redis的性能非常高,就不要持久化
如果要保证数据的完整性,要根据自己的业务来选择不同的持久化策略,一般情况都是使用混合模式
第一次配置的时候,切记吧aof打开(默认开启混合模式)
docker run -d -p 5001:6379 --name redis1 redis 主
docker run -d -p 5002:6379 --name redis2 redis 从
docker run -d -p 5003:6379 --name redis3 redis 从
docker exec -it redis1 /bin/bash ====》 redis-cli ===>
docker exec -it redis2 /bin/bash ====》 redis-cli ===> slaveof 192.168.1.211 5001 ===》info replication
docker exec -it redis3 /bin/bash ====》 redis-cli ===> slaveof 192.168.1.211 5001 ===》info replication
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现