[toc]
Redis 是一种高性能、高牢靠的内存数据存储和解决零碎,它反对多种数据结构和协定,能够用于各种不同的利用场景。本文将介绍 Redis 的高级个性,包含长久化、事务、Lua 脚本等方面,以及如何应用这些个性实现高性能、高牢靠的数据存储和解决。

高性能、高可用、高可扩展性的原理

  1. 基于内存的数据结构:Redis将数据存储在内存中,而不是硬盘中,因而能够实现十分高速的读写操作。
  2. 单线程的模型:Redis采纳单线程的模型,防止了多线程之间的竞争问题,也缩小了线程切换的开销。
  3. 高效的网络通信:Redis采纳本人设计的简略协定进行通信,协定自身十分轻量级,缩小了网络传输的开销。
  4. 异步非阻塞式IO:Redis采纳异步非阻塞的IO模型,当IO操作实现后才会告诉应用程序,防止了IO阻塞对性能的影响。
  5. 高效的长久化机制: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多平台公布