[toc]
Redis 是一种高性能、高牢靠的内存数据存储和解决零碎,它反对多种数据结构和协定,能够用于各种不同的利用场景。本文将介绍 Redis 的高级个性,包含长久化、事务、Lua 脚本等方面,以及如何应用这些个性实现高性能、高牢靠的数据存储和解决。
高性能、高可用、高可扩展性的原理
- 基于内存的数据结构:Redis 将数据存储在内存中,而不是硬盘中,因而能够实现十分高速的读写操作。
- 单线程的模型:Redis 采纳单线程的模型,防止了多线程之间的竞争问题,也缩小了线程切换的开销。
- 高效的网络通信:Redis 采纳本人设计的简略协定进行通信,协定自身十分轻量级,缩小了网络传输的开销。
- 异步非阻塞式 IO:Redis 采纳异步非阻塞的 IO 模型,当 IO 操作实现后才会告诉应用程序,防止了 IO 阻塞对性能的影响。
- 高效的长久化机制:Redis 反对多种长久化机制,包含快照和 AOF,能够满足不同的业务需要,同时也能够进步数据的安全性。
学会与人相处,建设良好的人际关系,这是退职场中获得成功的要害。
长久化
Redis 是一种内存数据库,它将数据存储在内存中,因而它十分疾速。然而,如果 Redis 过程意外终止,所有数据将失落。为了解决这个问题,Redis 提供了长久化性能,它能够将内存中的数据异步写入磁盘,以便在 Redis 重启后能够复原数据。
RDB 长久化
RDB 长久化是将 Redis 在某个工夫点上的数据保留到硬盘上,能够看作是对 Redis 内存中的数据做一个快照。RDB 长久化能够通过配置 Redis 服务器的工夫距离来主动触发,也能够手动执行。
AOF 长久化
AOF 长久化是将 Redis 的写操作以文本模式追加到文件中。AOF 文件中的每个写操作都是一个 Redis 命令,当 Redis 服务器重启时,能够通过执行 AOF 文件中的所有命令来复原数据。
长久化的配置
RDB 配置
RDB 长久化的配置文件为 redis.conf。在配置文件中,能够通过以下配置项来管制 RDB 长久化的行为:
- save:指定 Redis 主动触发 RDB 长久化的条件,格局为 save,其中 seconds 示意工夫距离,changes 示意数据变动的次数。例如,save 900 1 示意如果 900 秒内有至多 1 个键被批改,则触发 RDB 长久化。
- stop-writes-on-bgsave-error:如果设置为 yes,则如果 RDB 长久化失败,Redis 服务器将进行承受写申请,直到 RDB 长久化胜利为止。
Redis 还提供了以下与 RDB 长久化相干的命令: - save:手动触发 RDB 长久化。
- bgsave:在后盾异步执行 RDB 长久化。
AOF 配置
AOF 长久化的配置文件为 redis.conf。在配置文件中,能够通过以下配置项来管制 AOF 长久化的行为:
- appendonly:如果设置为 yes,则开启 AOF 长久化。
-
appendfsync:指定 AOF 缓冲区何时将数据同步到硬盘,有以下三个选项:
- always:每个 Redis 命令都会立刻同步到硬盘。
- everysec:每秒将 AOF 缓冲区中的数据同步到硬盘。
- no:齐全依赖操作系统将数据同步到硬盘。
- no-appendfsync-on-rewrite:如果设置为 yes,则当 Redis 执行 AOF 重写时,不将数据同步到硬盘。
Redis 还提供了以下与 AOF 长久化相干的命令: - bgrewriteaof:在后盾异步执行 AOF 重写。
- bgappendonly:在后盾异步执行 AOF 缓冲区的数据同步到硬盘。
长久化的复原
RDB 的复原
RDB 长久化的复原比较简单,只需将 RDB 文件复制到 Redis 服务器的工作目录,并在 redis.conf 文件中指定 RDB 文件的门路即可。Redis 服务器启动时会主动加载 RDB 文件,并复原数据。
人生如一场旅程,不要只看到目的地,更要享受旅途中的美妙。
AOF 的复原
AOF 长久化的复原绝对简单。首先,须要将 AOF 文件加载到 Redis 服务器中:
plaintextCopy code
redis-cli
CONFIG SET appendonly yes
BGREWRITEAOF
而后,须要清空 Redis 服务器中的数据:
plaintextCopy code
redis-cli
FLUSHALL
最初,执行 AOF 文件中的所有命令,复原数据:
plaintextCopy code
redis-cli
CONFIG SET appendonly yes
BGREWRITEAOF
RDB 和 AOF 的抉择
在抉择长久化形式时,须要依据理论的业务场景和需要来抉择 RDB 或 AOF 长久化。如果对数据完整性要求较高,能够抉择 AOF 长久化;如果对数据完整性要求不高,能够抉择 RDB 长久化。
长久化对性能的影响
长久化会对 Redis 服务器的性能产生肯定的影响,特地是在执行 RDB 长久化时,因为须要 fork 出子过程,会占用肯定的 CPU 和内存资源。因而,在配置长久化时,须要依据理论状况来均衡数据安全和性能的需要。
数据的失落问题
因为 Redis 的长久化是异步的,因而在 Redis 意外终止时,可能会失落局部数据。为了最小化数据失落的危险,能够应用 AOF 长久化,并将 appendfsync 设置为 always。这将确保每个写操作都同步到磁盘上的 AOF 文件中。
事务
Redis 事务是指在一次操作中执行多个命令,并且这些命令要么全副被执行,要么全副不执行。Redis 事务能够保障一系列命令的原子性执行。
职场中最重要的能力并不是技术或常识,
而是沟通和合作的能力。
事务的长处
- 原子性:Redis 事务能够保障多个命令的原子性执行,即要么全副执行,要么全副不执行。
- 性能:Redis 事务能够将多个命令打包成一个批量操作,从而缩小网络通信的开销,进步性能。
- 一致性:Redis 事务能够保障多个命令的一致性,即在执行事务期间,其余客户端不会对这些命令进行批改。
实现形式
- MULTI:开始一个事务。
- EXEC:执行事务中的所有命令。
- DISCARD:勾销事务。
- WATCH:监督一个或多个键,如果在事务执行期间这些键被批改,事务将被勾销。
示例:
/**
* 事务操作
* @param isOpenError 是否开启异样
*/
public void transactionalMethod(boolean isOpenError) {redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public List<Object> execute(RedisOperations operations) {operations.multi(); // 开启事务
ValueOperations<String, String> valueOps = operations.opsForValue();
valueOps.set("key1", "value1");
if(isOpenError){int i = 1 / 0;}
valueOps.set("key2", "value2");
List exec = operations.exec();// 提交事务
return exec;
}
});
}
注意事项
- Redis 事务不反对回滚操作。
- 如果在执行事务期间,键被其余客户端批改,那么事务将被勾销。
- Redis 事务不反对嵌套事务。
- Redis 事务中的命令不能应用事务外的数据。
- Redis 事务中的命令不反对乐观锁。
利用场景
- 批量操作:将多个命令打包成一个事务,从而缩小网络通信的开销,进步性能。
- 保证数据一致性:在须要保证数据一致性的场景中应用 Redis 事务能够防止因为并发操作导致数据不统一的问题。
公布订阅
公布和订阅是 Redis 的一种消息传递机制,它能够实现多个客户端之间的音讯通信。上面是一个简略的 Redis 公布和订阅的示例
实现音讯订阅者
public class RedisMessageListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] bytes) {System.out.println("收到音讯:" + message.toString());
}
}
注册音讯订阅者
@Bean
public RedisMessageListenerContainer redisContainer() {RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisTemplate().getConnectionFactory());
container.addMessageListener(new RedisMessageListener(), new ChannelTopic("pubsub:example"));
return container;
}
发送音讯
public void publish(String message) {redisTemplate.convertAndSend("pubsub:example", message);
}
lua 脚本
永远放弃虚心和学习的心态,
能力一直晋升本人,博得更多的机会和尊重。
Redis 反对 Lua 脚本,能够通过编写 Lua 脚本来实现简单的数据操作和解决。Redis 的 Lua 脚本能够拜访 Redis 数据库,Redis 提供的各种命令和函数。
上面是一个应用 lua 脚本实现 redis 自增计数器的示例
public Long increment(String key) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();
script.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/increment.lua")));
script.setResultType(Long.class);
List<String> keys = Collections.singletonList(key);
return redisTemplate.execute(script, keys);
}
lua 脚本
local key = KEYS[1]
local value = redis.call('INCR', key)
return value
应用 Lua 脚本能够将多个 Redis 命令封装在一个脚本中,缩小网络开销和服务器负载。此外,Lua 脚本还能够实现 Redis 不反对的数据结构和算法,能够扩大 Redis 的性能和利用范畴。
管道操作
管道(pipeline)是一种高效的 Redis 命令执行形式,它能够在一次通信中发送多个 Redis 命令,并一次性获取所有命令的响应后果。这种形式能够无效地升高 Redis 服务器的网络提早和通信开销,进步 Redis 的性能。
上面是一个应用管道操作的示例
/**
* 管道操作
* 留神管道操作不反对事务和 watch 命令,须要审慎应用。* 管道操作会将多个命令打包成一个申请发送给 Redis 服务器,* 如果其中一个命令执行失败,那么整个管道操作都会失败
*/
public void pipelineExample() {List<Object> results = redisTemplate.executePipelined(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {connection.stringCommands().set("key1".getBytes(), "value1".getBytes());
connection.stringCommands().set("key2".getBytes(), "value2".getBytes());
connection.stringCommands().set("key3".getBytes(), "value3".getBytes());
return null;
}
});
System.out.println(results); // 打印后果
}
残缺代码地址
https://gitee.com/youlaiorg/youlai-learning.git
总结
本文介绍了 Redis 的高级个性,包含长久化、事务、公布订阅、lua 脚本和管道操作。其中,长久化能够实现数据的长久化存储,事务能够保障一系列命令的原子性执行,公布订阅能够实现多个客户端之间的音讯通信,lua 脚本能够实现简单的数据操作和解决,管道操作能够在一次通信中发送多个 Redis 命令。此外,本文还介绍了 Redis 高性能、高可用、高可扩展性的原理,包含基于内存的数据结构、单线程的模型、高效的网络通信、异步非阻塞式 IO 和高效的长久化机制。
做事要讲求团队单干,相互支持,共同进步。
本文由 mdnice 多平台公布