Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1851136
  • 博文数量: 184
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2388
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
个人简介

90后空巢老码农

文章分类

全部博文(184)

文章存档

2021年(26)

2020年(56)

2019年(54)

2018年(47)

2017年(1)

我的朋友

分类: NOSQL

2019-05-11 23:06:28

redis在进行持久化(aof或者rdb,这个以后会讲到,暂时理解是两种不同的方式将内存中的数据同步到磁盘)的时候,开始都是直接fork一个子进程出来,然后让这个子进程取进行持久化工作,在这期间,父进程照样工作,对外提供服务,接收到的命令也都缓存起来,子进程执行完任务之后,通知父进程,父进程收割,将缓存的命令同步到磁盘,最后OK。但是这样会出现一个问题,就是在子进程执行任务期间,如果父进程中缓存过多的数据就会造成性能下降,redis的大佬们就想出了利用管道来进行父子进程之间通信的方式来优化,就是子进程执行期间,将父进程接收到的命令通过管道来写给子进程,这样能够减少父进程收割完子进程之后,写入磁盘的数据的数目。
在redis当中简单的管道实现如下:
1. 打开:

点击(此处)折叠或打开

  1. void openChildInfoPipe(void) {
  2.     if (pipe(server.child_info_pipe) == -1) {
  3.         /* On error our two file descriptors should be still set to -1,
  4.          * but we call anyway cloesChildInfoPipe() since can't hurt. */
  5.         closeChildInfoPipe();
  6.     } else if (anetNonBlock(NULL,server.child_info_pipe[0]) != ANET_OK) {
  7.         closeChildInfoPipe();
  8.     } else {
  9.         memset(&server.child_info_data,0,sizeof(server.child_info_data));
  10.     }
  11. }
2. 关闭:

点击(此处)折叠或打开

  1. /* Close the pipes opened with openChildInfoPipe(). */
  2. void closeChildInfoPipe(void) {
  3.     if (server.child_info_pipe[0] != -1 ||
  4.         server.child_info_pipe[1] != -1)
  5.     {
  6.         close(server.child_info_pipe[0]);
  7.         close(server.child_info_pipe[1]);
  8.         server.child_info_pipe[0] = -1;
  9.         server.child_info_pipe[1] = -1;
  10.     }
  11. }
3. 发送数据给parent

点击(此处)折叠或打开

  1. /* Send COW data to parent. The child should call this function after populating
  2.  * the corresponding fields it want to sent (according to the process type). */
  3. void sendChildInfo(int ptype) {
  4.     if (server.child_info_pipe[1] == -1) return;
  5.     server.child_info_data.magic = CHILD_INFO_MAGIC;
  6.     server.child_info_data.process_type = ptype;
  7.     ssize_t wlen = sizeof(server.child_info_data);
  8.     if (write(server.child_info_pipe[1],&server.child_info_data,wlen) != wlen) {
  9.         /* Nothing to do on error, this will be detected by the other side. */
  10.     }
  11. }
4. 接收parent的数据

点击(此处)折叠或打开

  1. /* Receive COW data from parent. */
  2. void receiveChildInfo(void) {
  3.     if (server.child_info_pipe[0] == -1) return;
  4.     ssize_t wlen = sizeof(server.child_info_data);
  5.     if (read(server.child_info_pipe[0],&server.child_info_data,wlen) == wlen &&
  6.         server.child_info_data.magic == CHILD_INFO_MAGIC)
  7.     {
  8.         if (server.child_info_data.process_type == CHILD_INFO_TYPE_RDB) {
  9.             server.stat_rdb_cow_bytes = server.child_info_data.cow_size;
  10.         } else if (server.child_info_data.process_type == CHILD_INFO_TYPE_AOF) {
  11.             server.stat_aof_cow_bytes = server.child_info_data.cow_size;
  12.         }
  13.     }
  14. }

阅读(10763) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~