[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 coderedis-cliCONFIG SET appendonly yesBGREWRITEAOF
而后,须要清空Redis服务器中的数据:
plaintextCopy coderedis-cliFLUSHALL
最初,执行AOF文件中的所有命令,复原数据:
plaintextCopy coderedis-cliCONFIG SET appendonly yesBGREWRITEAOF
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多平台公布