关于复述,你可能不了解的一些事

  


  

  

复述是一个高性能分布式的键值数据库。它支持多种数据结构,并可应用于缓存,队列等多种场景下。使用过复述的小伙伴们可能对这些已经非常熟知了、下面我想来谈谈复述,也许并不被每个人了解的那点事。

  


  

  

刚看到标题你可能会说,我知道,不就是RDB和AOF嘛。这些已经是老生常谈了。那么我们今天就深入谈谈这两种持久化方式的逻辑和原理。

  

<强> RDB的原理

  

在复述中RDB持久化的触发分为两种:自己手动触发与复述,定时触发。

  

针对RDB方式的持久化,手动触发可以使用:

  
  

(1)节省:会阻塞当前复述,服务器,直到持久化完成,线上应该禁止使用。
  (2)bgsave:该触发方式会叉一个子进程,由子进程负责持久化过程,因此阻塞只会发生在叉子进程的时候。
  

     

而自动触发的场景如下:

  
  

根据我们的拯救mn配置规则自动触发;
  从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发bgsave;
  执行调试重载时处罚;
  执行关闭时,如果没有开启aof,也会触发。
  

     

由于拯救基本不会被使用的到,我们来看看bgsave这个命令是如何完成RDB的持久化的。

  

关于复述,你可能不了解的一些事”> <br/>
  </p>
  <p> RDB文件保存过程</p>
  <blockquote>
  <p>(1)复述,调用叉,现在有了子进程和父进程。<br/>
  (2)父进程继续处理客户请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制(复制alt=

  
  

(1)复述,调用叉,现在有父子两个进程
  (2)子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
  (3)父进程继续处理客户请求,除了把写命令写入到原来的aof文件中,同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
  (4)当子进程把快照内容写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
  (5)现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
  

     

需要注意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

  


  

  

复述,采用的是基于内存的单进程单线程模型的KV数据库,由C语言编写,官方提供的数据是可以达到100000 +的每秒(每秒内查询次数)。这个数据不比采用单进程多线程的同样基于内存的KV数据库Memcached差!原因如下:

  
  

1,完全基于内存,绝大部分请求是纯粹的内存操作,非常快速;
  2、数据结构简单,对数据操作也简单,复述中的数据结构是专门进行设计的;
  3,采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU、不用去考虑各种锁的问题,不存在加锁释放锁的操作,也不可能出现死锁而导致的性能消耗;
  4、使用多路I/O复用模型,非阻塞IO;
  5、使用的底层模型不同,底层实现方式以及与客户端之间通信的应用协议不一样,复述,直接构建了自己的VM机制。
  

     

<强>多路I/O复用模型

  

多路I/O复用模型是利用选择、调查,epoll可以同时监察多个流的I/O事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路I/O复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)。

  

  

复述中的事务(事务)是一组命令的集合。事务同命令一样都是复述最小的执行单位,一个事务中的命令要么都执行,要么都不执行.Redis事务的实现需要多和执行两个命令,事务开始的时候先向复述,服务器发送多命令,然后依次发送需要在本次事务中处理的命令,最后再发送EXEC命令表示事务命令结束。

关于复述,你可能不了解的一些事