Redis实现之虚拟存储系统(VM)实现(四)–线程式虚存(Threaded VM)交换

2011年8月6日 sigma 7 条评论 6,799 views

非阻塞虚存的几种实现选择

由于阻塞式虚存实现有各种缺点,因此,Redis实现了非阻塞式的虚存系统。实现非阻塞式虚存系统有以下几种方法:

  1. 最显然的方法,就是把整个redis做成多线程的,每个数据库操作都是自动分配到某个线程(或者fork一个新的线程),这样就不存在阻塞的问题。但是这对redis不是一个好的解决方案,因为为了实现提高操作速度,redis没有锁,保证原子性是通过顺序执行来保证的,因此整个redis引入多线程要增加锁,导致速度变慢(也许多核上能快点),并且极大增加代码量(现在redis只有1万行代码)。
  2. 通过非阻塞式IO实现,由于redis是基于事件循环的(event-loop based),可以采用非阻塞IO。但redis的作者基于以下两点把这个否了:①非阻塞文件操作不像sockets,会导致很多不兼容的问题,这和操作系统紧密相关,要做很多和操作系统相关的工作。②另外一个原因就是,在虚存中,文件IO操作仅仅是一部分,还有很多事件花在数据的编解码上面(编解码成交换文件swap file)。
  3. 于是就剩下最后一种方法,通过增加IO线程来完成数据交换。

下面,具体介绍第三种实现,即IO线程:

IO线程

IO线程的设计目标依重要性排列如下:

  • 实现简单:尽量减少数据冲突(race)的可能性;用简单的锁;VM的代码要能够和Redis的其他代码分离(个人感觉这符合设计正交性原则)。
  • 高性能,对于客户端访问数据不会造成锁(等待)。
  • IO线程要能够编解码交换文件(针对第二种实现的缺点2)。

鉴于以上目标,Redis 的非阻塞VM实现的方式为,实现了一个redis主线程(实际和客户端交互的线程,处理请求),以及一些通过一个简单的信号量(mutex)和任务队列进行通信的IO进程。简单的说,主线程将IO请求交给IO线程进行后台处理(通过将一个(IO)任务结构交给server.io_newjobs队列)。假如没有IO进程,则新建一个。有些IO进程完成IO任务后,结果将发送到server.io_processed队列。IO进程将通过UNIX管道给主进程一个信号,以便告知已经完成,可以继续新的任务。

阅读全文…

点点网绑定独立域名方法

2011年8月2日 sigma 3 条评论 11,165 views

今天看到一个同学的点点绑定了独立域名,感觉不错,于是也想把自己的点点也绑个独立域名。

下面是绑定方法:

首先官方的方法:

绑定独立域名可以给你的博客设置独立顶级域名,比如”www.mywebsite.com”。其他人访问这个地址的时候会自动跳转到你的点点博客;设置的过程比较复杂,不过不用担心,跟随我们的说明向导一步步完成:)

请注意:域名绑定功能需要用户先进行域名备案,备案流程如下,整个备案流程完全免费;关于绑定域名的任何问题都可以联系 cname@diandian.com ;

绑定域名的流程如下:

  1. 首先需要发送一封包含以下内容信息的申请邮件到 cname@diandian.com ;-你的点点博客地址(子博客也要列入)
    -要绑定的域名和对应的点点博客
    -你的真实姓名
    -你的身份证号码
    -你的联系方式(最好手机,方便我们随时联系到你)
  2. 我们的工作人员会对每一封申请域名绑定的邮件进行审核处理,通过审核的我们将协助进行域名备案开通绑定,没有通过的我们将邮件通知您;
  3. 开通博客域名绑定之后别人访问绑定的独立域名将会直接访问你的点点博客,访问点点博客xxx.diandian.com将会自动跳转到新的独立域名www.xxx.com了,你的所有的内容都会出现在新的独立域名下面。

关于域名绑定的任何问题都可以联系 cname@diandian.com 。

阅读全文…

Redis实现之虚拟存储系统(VM)实现(三)–阻塞式虚存(Blocking VM)交换

2011年7月24日 sigma 2 条评论 5,538 views

个人理解,所谓阻塞式虚存(Blocking VM),是指redis发生数据交换时,进程被阻塞,不能干其他的事情(后面一篇文章将讲到Threaded VM相反,有独立VM线程)。

在Redis中,启用阻塞式虚存需要在配置文件中将server.vm_max_threads设成0(即不为Threaded VM),和VM另一个相关配置变量是sever.vm_max_memory,它表示Redis中数数据所占用的最大内存(实际上运行过程中可能大于这个值),只有数据量占用内存大于这个值时,才会出现数据交换到disk。

交换到硬盘

数据交换是通过一个计划任务函数(cron function)实现的。这个函数每隔一定的时间会检查是否超出了内存最大值(out of memory)。假如发现超出了最大值,则通过循环调用vmSwapOneObject(这个函数只有一个参数,0表示阻塞式,1表示线程式)来将数据交换到硬盘。

vmSwapOneObject实现如下:

  1. 和Cache替换一样,很关键的一点就是需要找到需要交换出去的Object,使得交换代价最小(后面会讲redis是如何决定的)。
  2. 被交换出去的object关联的值(value)通过阻塞式被交换到硬盘。
  3. key的storage域被设置成REDIS_VM_SWAPPED,vm域也将改写,包括页表索引值,以及所占用的页数。
  4. 释放被swap的object的内存,在哈希表(hash table)中将对应的value的入口设置成NULL。

这个函数一直被调用,直到如下情况:swap空间已满,或者数据对象占用的内存小于sever.vm_max_memory。

阅读全文…

Redis实现之虚拟存储系统(VM)实现(二)–数据交换(Swap)的实现

2011年7月17日 sigma 4 条评论 54,673 views

Redis的虚拟存储系统(VM subsystem)的目的是实现将Redis对象(Redis Objects)方便的在主存(Memory)和硬盘(Disk)之间交换。在Redis虚拟存储系统中,Redis仅仅会将和值(Values)关联的对象交换(swap)到硬盘上。在前一篇日志中,对VM涉及的数据结构进行简要介绍,在这篇日志中,将介绍数据交换的具体过程。

在具体讲Redis数据交换的具体实现之前,有必要讲下swap文件,swap文件是由若干页(page)组成的,每页包含着给定字节数的数据。由于不同的redis实例的最优配置不一样(取决于你实际存储数据的大小),这些参数可以通过redis.conf文件进行修改。下面是默认的大小:

 vm-page-size 32
vm-pages 134217728
 

Redis使用位向量(英文为bitmap,这是一些连续的位,每位的值为0或1)来表示在硬盘中page是否被使用。假如一个给定位是1,则表示该页被使用(有swap文件存在上面),为0,表示该页未被使用。

通过在内存中使用位向量(下面将称为页表位向量),可以在很少的内存消耗情况下取得巨大的性能提升,因为我们仅仅只需要为每页提供一位。对于上面的默认配置,总共有4G的虚存,但是只需要16M的内存给页表位向量。

为了将主存上的数据交换到交换空间,我们需要做如下步骤(假设没有使用虚存线程,仅仅是块实现)。

  1. 找出需要多少页来存储交换文件。这仅仅需要通过调用rdbSavedObjectPages函数即可返回需要的页数。
  2. 知道需要的页数后,我们需要找到交换空间中一些连续的页来存储。这是通过vmFindContiguousPages函数实现的。这个函数有可能因为内存满了而失败,也有可能因为找不到连续的页失败。当这种情况发生时,交换将被取消,数据将继续保存在内存中。
  3. 最终,我们只需要调用vmWriteObjectOnSwap函数即可以将数据交换到对应的位置。数据交换完成后,对应的主存被释放,对应的key也被标记为REDIS_VM_SWAPPED,而对应的页表位向量也被标记为使用中。
    而将交换空间的数据切回到主存中,则很简单,由于知道对象存的位置以及占用页数。只需要调用vmLoadObject即可以完成。

注:本文内容翻译自redis源码包doc目录中的相关文档。

Scanf通过%x(%d)读入char出现栈溢出的诡异问题

2011年7月11日 sigma 4 条评论 8,221 views

昨天使用scanf(fscanf)碰到一个很诡异的问题,问题抽象出来是这样的:

有如下代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	FILE *fin;
	int i;
	unsigned char a[8];
	fin=fopen("test_file","r");

	for(i = 7; i >= 0 ; i--)
//	for(i = 0; i <= 7 ; i++)
	  {
		  fscanf(fin,"%x",a+i);
		  printf("%2x ",a[i]);
	  }
	printf("\n");
	for(i = 7; i >= 0 ; i--)
	  {
		  printf("%2x ",a[i]);
	  }
	printf("\n");
	fclose(fin);
	return 0;
}

其中test_file的内容是:11 22 33 44 55 66 77 88 99 阅读全文…

分类: study 标签: , ,

无觅相关文章插件,快速提升流量