Reprinted: RAMCloud malloc memory allocation and release of the principle of free memory

  Now the whole array of flash memory has been surprised, EMC's XtremIO, there VNX-F (Rockies), IBM FlashSystem. All Flash is a real efficiency and health, redefining storage speed. With extreme performance, high availability, you greatly improve the efficiency of enterprise applications. Mentioned advantages of flash memory, then no doubt is speed! Behind the speed advantage, SSD are faced with restrictions of price, capacity and life.

      Of course, with the development of technology, cost reduction, SSD is likely to replace the mechanical hard drive, has become the main medium of the next generation of enterprise storage. Mechanical hard drive could turn into a magnetic tape.

       However, flash memory speed really is the limit right now storage system? Now there is a need memory-based database, such as Redis, TimesTen. We must mention also excellent practice memcached caching system. also the middle spark data manipulation are all fit into memory, avoiding the problem of real-time availability and poor Hadoop, it is possible to have a profound impact on the ecosystem of Hadoop. spark has on February 27, 2014 officially became the top-level Apache Foundation project.

      RAMCloud, is a full use of DRAM memory systems, it's all data stored in memory. Of course, the order will RAMCloud Recovery backup logs and data persistence to the ordinary hard disk. In 2014 FAST Conference, RAMCloud published a paper on memory allocation and management mechanism, and was named the best paper, after I read this article, the formation of this article to share experiences.

1. Why not use malloc?

    And now a lot of memory allocator, such as malloc C's, Google's tcmalloc. Of course there are Java memory management and GC. But they have a few problems, one is under the efficient, very prone to memory fragmentation in the access mode changing. Experiments show that only make use malloc memory utilization up to 50%.

    memory allocator can be divided into two categories: non-copying and copying. non-copying allocator is no longer move after the memory allocation in it. For a single program, this distribution is very natural, because after all, these memory once it's basically the size of the application will not be changed. However, for a storage system, the file can be modified, such as increased or decreased, so if using the malloc, need to apply for a new memory block, then it is easy to produce fragments. For example, a piece of the new system beginning 100B size of the file, and later increased to some files 130B, then release the space 100B has the potential to produce debris, such as later did not write <= 100B in size. (Note: memory fragmentation indeed this memory storage system is very easy to produce, and the design of test cases indeed makes it the largest malloc memory utilization to 50% but the actual production environment is like this now unknown. in short RAMCloud memory allocation and management is indeed very good, but if malloc whether it is really so unbearable in a production environment, it can not be conclusive. About malloc memory allocation, please refer to " the principle of free memory malloc memory allocation and release of " ).

     For copying allocator, can indeed solve the problem of fragmentation by garbage collector. But the disadvantage is the need to go through all the data to be able to reallocate. However, in consideration of performance, you need a lot of extra memory (1.5 to 5 times). Such increase will be lost to memory usage by fragments of the original intention of the management. And there is a problem that needs a long period of suspension of service. Take Java's GC, it takes 3-4 seconds, this time for RAMCloud, it has been possible to detect a node failure and recover data up to 64GB. (Note: I do not know whether it is improper use of Java makes this wronged, even though it is indeed a problem)

2. RAMCloud Overview

       Since this paper to elaborate on memory allocation management log, this section describes the storage of management, and why you should allocate memory based log management mechanism, and discard the original.

      RAMCloud most appropriate scene is already the server is divided into application servers (mainly realizes generate Web pages and execute business rules application logic) and the storage server (shared storage to provide long-term application server) data centers. These data centers are typically support many applications, some very small, only a portion of the capacity of a single server, and some great use to the thousands of dedicated application and storage servers.

      Moreover, the information stored in the cloud must be lasting memory and hard disk as a single storage server failure does not cause data loss and even a few seconds of the service is unavailable. RAMCloud all the data stored in the DRAM, the performance can be achieved than the current highest performance disk storage system 100 to 1000 times higher still. In terms of access latency, a process RAMCloud program running in an application server reads from the storage servers in the same data center through a network of hundreds of bytes of data just 5 ~ 10μs, and now the actual system generally takes 0.5 ~ 10ms, depending on the data in the server memory cache, or hard disk. Moreover, a multi-core storage server can serve at least 100 million times smaller read requests per second. The hard disk system, the same machine can serve only 1,000 to 10,000 requests per second.
     The system architecture is shown below.

     


       Each storage server contains two parts: Master and Backup. Master managed object stored in the memory of. Backup using local mechanical hard drive or solid state drive to save the backup data to other server. Coordinator of the Master and Backup management configuration information, such as clustering and distribution relationship between each individual backup server. Coordinator but not involved in the data read and write operations, and therefore will not be reduced or scalability bottleneck cluster system.

      RAMCloud提供了一个简单的key-value的数据模型,数据(称为object)都是连续存储的。每个object都被长度不一的唯一的key标记。多个object被保存到table中,这个table有可能跨越多个server。object只能以整体的方式进行读写。它为小object做了专门的优化,这也非常适合超大规模的web并发的请求。

     每个Master都有自己的日志,这些日志被分成8M的块,成为segment(段)。每个segment都会冗余到其他的server的Backup,典型的配置都是冗余2-3块。在client写操作的时候,冗余发送到其他的节点,这些节点在把冗余写到memory的buffer后就会返回,而不是保存到本地磁盘后才返回,这样保证了client的高速度写入。这些buffer在某些时间点会flush到本地存储。

3. Log Metadata

    在基于日志的文件系统中,为了快速的访问日志数据,日志中使用了各种索引。RAMCloud是使用了hash table来访问在memory中的数据。硬盘中的日志在正常工作的环境下是永远用不到的。它唯一被用到的机会就是故障恢复。日志一共分为三种:

1). 元数据

    包含了存储基本单元object的table id,key,version,value。在数据恢复时,将根据最新version的条目来重建hash table。

2). 日志摘要(log digest)

    每一个新的日志段都会有一个日志摘要,这个摘要包含了所有属于这个段的日志。在数据恢复时,将根据段的最新的日志摘要来加载所有的元数据。

3). tombstone(墓碑?)

    这个日志是比较特殊的。它代表了被删除的object。日志一旦写入就不可修改,那么如果一个object被删除怎么办?在日志中添加一条tombstone的记录。记录包含table id,key和version。在平时的操作中,tombstone是不会用到。但是在数据恢复时,它能保证被删除的object不会被重建。

   tombstone的机制很简单但是也有很多问题。其中一个问题就是它的GC,毕竟它最终要在log中删除。只有在object被删除后,tombstone才能被删除。否则也就违背了引入tombstone的初衷了:通过它来防止被删除的object的重建。在cleaner处理tombstone的log时,它会检查tombstone所指定的segment是否不在任何的log中。如果不在,那么说明object已经被删除,否则说明该segment还有有效数据,该tombstone不能被删除。

4. Two-level Cleaning

      对于基于日志的内存分配,主要的瓶颈就在于log cleaner。碎片管理,或者说内存回收是非常昂贵的,这就需要巧妙的设计。特别是随着内存利用率的上升,回收的成本也越来越大。例如,对于一个内存利用率80%的情况,为了获取2B的可用空间,平均情况下需要移动8B的数据。如果是90%,那么移动9B的数据只能带来1B的空间。见下图的上半部分。

     对于Memory来说,带宽不是问题,我们关注的是空间的利用率,毕竟相对来说DRAM还是比较贵的。对于硬盘来说,带宽是昂贵的,可以说很多系统的瓶颈都是在硬盘的IO读写速度上,这也催生了很多基于memory的各种解决方案,当然也是RAMCloud需要解决的问题。因此,RAMCloud对于memory和disk采取了两种不同的回收策略。

    两个阶段的cleaning,使得memory的cleaning可以不影响Backup,这个结果就是一般来说memory的利用率要高于disk。memory的利用率可以达到90%,disk的要低得多。当然因为disk的cleaning的频率更低,这也就可以理解了。

   第一个level的cleaning,成为segment compaction,仅仅是处理了in-memory的segment,并没有消耗网络或者disk的IO。它每次压缩一个segment,将它上面的数据拷贝到其他的segment,这样空出来的segment可以为其它所用。segment compaction在memory和disk中都维持了相同的log。但是由于在memory中的segment中删除的object和tombstone都已经被彻底删除了,因此它实际上占用了更少的空间。入下图所示。

  

第二个level的cleaning称为combined cleaning。顾名思义,这一level的cleaning不单单会cleaning disk的,同样也会cleaning memory的。因为已经有segment compaction了,因此这一level的cleaning也是很有效率的。而且因为这一阶段被延后进行了,可以合并更多的删除操作了。

4.1 seglet 

    如果没有segment compaction,那么所有的segment都有相同的大小,默认情况下是8MB。因为有了压缩,因此segment可以有不同的大小。当然我们不能采用传统的heap allocator,因为那会产生碎片。RAMCloud将segment分为64KB的seglet。每个segment分为不同的seglet,seglet的数量就决定了segment的大小。你可能也有疑问,seglet的引入肯定也会引入碎片。实际上,对于一个segment来说,只可能产生大约1/2个seglet大小的碎片,也就是32KB/8MB = 1/64=1.5%。也是由于seglet的引入,log现在变得不连续了,因为log有可能跨越多个seglet,RAMCloud使用了额外的机制来处理这种情况。

4.2 clean的触发机制

    two-level的cleaning的引入,引入了一个新的问题:什么时候触发segment compaction,什么时候触发combined cleaning?这个选择将会影响到系统的性能,因为combined cleaning占用了系统珍贵的disk IO和network IO。这个policy 模块,称为balancer。接下来简要的介绍一下balancer的机制。

    一般情况下,在memory和disk的利用率不是很高的情况下,cleaner是不会工作的。因为cleaner的提早工作并不会有多高的效率。相反,如果cleaner的工作延后,那么可以处理更多的删除的object,可以回收更多的空间资源,因此,延后的cleaner是非常有意义而且有好处的。

    那么如何判断memory的剩余空间已不足呢?balancer通过以下方式进行判断:假设L代表live objects所占用的空间使用率,F代表未分配的seglet所占整个空间的使用率,那么如果F <= min( 0.1, ( 1 - L )/2 ),那么cleaner就要开始工作了。一方面,cleaner会尽量的延后工作使得回收工作更有效率,另一方面,当预测到系统有可能会run out-of-memory时,cleaner会立即启动以回收memory以保证有更多的memory可以使用。

     那么选择segment compaction呢,还是选择combined cleaner呢?一般来说,compaction会优先考虑因为它更有效率。但是有两种情况下必须启动combined cleaner:第一种情况就是tombstone太多了。因为segment compaction是不能单独把tombstone标记的数据删除的,它必须将这些数据从backup中删除之后才可以删除在memory中的tombstone。由于tombstone的越来越多,使得memory的使用率越来越高,导致compaction越来越低效。最终,选择combined cleaner可以是系统删除那些tombstone,也会使得以后的segment compaction更有效率。

     那么如何计算tombstone的多寡呢?balancer通过以下公式:假设T代表live tombstone所占用的空间使用率,L as above,T/( 1 - L ) >= 40%。也就是说,当tombstone占用了超过40%的可用空间的时候,combined cleaner会启动以删除这些tombstone,回收空间。40%是通过不同的条件,不同的负载下测试得出的经验值。从这个公式也可以得出,在有很多小文件的使用场景下,这种cleaner会频繁的调用。

     第二个原因就是on-disk log太大时,为了防止disk run out-of-space,也为了避免系统恢复时重建时间太久,都会启动combined cleaner。


     小结一下,balancer在未使用的空间率太低时会启动segment compaction并且a)disk space使用率较低 和b) tombstone不多。

5. Parallel Cleaning

     现在CPU的主频已经打破了摩尔定律了,但是CPU的核心数不断增加。现在16 core,32 core的server CPU已经非常常见了。RAMCloud也充分利用了CPU 的multi-Core: 同时以多线程执行cleaner。

    因为log的结构和简单的meta-data,使得cleaner的并行执行变得简单。因为log是不可修改的,cleaner在复制移动object时就不必担心这些object会被修改。而且,hash table存储的也是object的间接地址,因此更新hash table的object reference变得很简单。因此基本的clean机制也变得简单起来:

     cleaner 拷贝live data到新的segment,也就自动的更新了hash_table的object reference,最后将cleaned segment就释放出来了。

     在clean线程和service线程在处理读写请求时有三个地方需要注意:

  1. 它们都需要在log的head添加数据
  2. 它们在更新hash table可能会有冲突
  3. 当segment在被某些service线程使用的时候,cleaner不能释放它们。

5.1 日志的并发更新

   最简单的cleaning方法就是把需要移动的数据添加到log的头部。但是这样话的会和service的写请求冲突。为了避免这种情况,RAMCloud是将这些需要移动的数据移动到一个新的segment。每个cleaner都会申请一组segment用于保存移动的数据,只有在申请segment的时候需要同步。在申请完成后,每个cleaner就可以操作自己所属的segment了而无需额外的同步操作。在移动完成后,cleaner会把这些segment放到下一个的log digest中,同时被回收的segment也会在下一个log digest中也会被删除。而且将这些数据移动到不同的segment而不是head segment中还有另外的好处:这些segment可以备份到不同的disk中,可以提高Master的吞吐量。

5.2 Hash Table的争夺

       Hash Table由于同时被cleaner和service threads使用,因此会有同步的问题。Hash table标明了哪些object是可用的并且保存了在memory中的地址。cleaner使用Hash table去确定某个object是否alive:通过判断指向的地址是否真的是该object,如果是alive的,他就将Hash table中更新该object中的新地址。同时,service线程通过Hash table来读
取或者删除某个object。RAMCloud现在使用在每个hash的bucket上使用一个fine-gained lock来同步。

5.3 释放内存空间的时机

      当cleaner thread clean完成一个segment后,这个segment的空间可以被释放或者被重用。在这个时间点,所有service thread都不会看到这个segment的数据,因为没有hash table的条目指向这个segment。但是有可能老的service thread还在使用这个segment。所以free这个segment可能会导致非常严重的问题。

    RAMCloud采用了一个非常简单的机制来处理这个问题:系统直到所有当前的service thead数据请求处理完成才会释放该segment。当然的service thread处理完成之后,释放segment是安全的,因为所有后来的service thread都不可能使用到这个segment。这个设计很简单,避免了使用锁来完成这个普通的读写操作。

5.4 释放disk空间的时机

       当segment被clean后,在backup上的冗余备份也需要删除。然而,这个删除只能在被移动到的segment正确的写到on-disk中的日志之后。这需要两个步骤。

  1. 合并后的segment需要在backup中完成冗余拷贝。因为所有的冗余拷贝都是异步进行传输的,因此只有cleaner在接收到所有的响应接到后。
  2. 新的log digest必须包含新的合并的segment和删除被clean的segment。

只有上述数据被持久化后,这个冗余备份就可以被安全的删除了。

6. Avoiding Cleaner Deadlock

     由于clean的过程中需要额外的内存,因此在内存利用率高的时候,clean的过程中有可能会耗掉最后的内存,run out-of-memory。因此形成了deadlock。

     RAMCould为了避免这种deadlock采取了多种技术,首先,它会为cleaner申请一个seglet的pool。使得不会因为seglet的申请而导致死锁。而且,它在clean一个segment时,会计算是否这个clean会带来空间的利用率升高。比如下图这个例子的clean会导致碎片更大,反而导致了空间的浪费。

   

    还有一个措施是会申请专门的log digest以免申请额外的log digest时导致内存耗尽。

    综合以上技术,RAMCloud的空间利用率可以达到98%,而不会产生deadlock。

7. RAMCloud的未来

   首先声明本节内容不是来自于paper,而是搜集自网络。

7.1 对比SSD

    基于DRAM存储设备比基于闪存的存储设备速度更快,但成本也要高得多。
    比如,2TB大小基于闪存的存储设备成本大约为18万美元;相比之下,存储容量相同但基于DRAM的存储设备成本高达约100万美元。基于DRAM的驱动器读取或写入数据的时间只要0.015毫秒,工作状态下随机速度达到了每秒可以处理40万次I/O。这种驱动器最适合以写操作为主的软件以及使用高性能数据库应用系统的公司。
    基于闪存的存储驱动器读取或写入数据的时间为0.2毫秒,工作状态下最高读取速度为每秒10万次I/O,最高写入速度为每秒2.5万次I/O。这项技术也更适合以读操作为主的应用。

7.2 应用场景

    首先,RAMCloud可以是一个数据密集型应用的新架构,传统的架构是应用程序连同代码和数据被加载到一台服务器的主存储中,瓶颈也是显而易见的,各种复杂的数据操作,应用程序的大小,机器的处理能力都是瓶颈。
    而在过去的10年中,一种服务于数百万用户的大型WEB应用架构出现了。其主要将应用程序代码和数据存放于同一个数据中心中的不同服务器中。应用服务器只存储当前请求和处理浏览器的需求,而这种架构允许应用程序扩展到成千上万的应用服务器和存储。
    但是不幸的是,在大型架构图中,当服务器增加了4-5个数量级后,应用程序的复杂性,数据的访问延迟都成了问题。比如当Facebook收到一个HTTP请求访问网页时,应用服务器必须发出130个以上的数据以生成HTML页面,这当中有指令请求的顺序,而这些请求指令的累积是造成给用户整体响应时间延迟的因素之一,所以需要相当大的开发量,以尽量减少对服务器请求的代码大小和数量。
    Mapreduce是最近几年兴起的一个新的技术,目的在于提高数据接入速度,消除了延迟问题,现在它解决了大规模的问题,但是如果是连续的数据访问,将使得Mapreduce仅仅限于在随机访问数据的应用中使用。
    RAMCloud则充分结合了两者的优势——规模化和低延迟:保留了Web应用程序的可扩展性,同时降低了数据访问延迟以接近传统的应用程序。

    过去所有的Web应用程序都使用关系型数据库存储,但随着数据规模的扩大,一个单一的关系型数据库已经不能满足他们的I/O需求。因此大家开始做系统升级,引进新的技术来扩展自己的存储系统(比如多个数据库间的数据分区)。
    比如,尽管Facebook在2009年的时候就有4000个MySQL服务器,但由于大量交互式数据的调用,现有的存储系统依旧不能满足它的I/O需求,所以Facebook用了2000个Memcached用作分布式内存对象缓存服务器——将一些键值存储于主内存中,但其瓶颈在于,需要处理Memcached和MySQL服务器之间的一致性,需要对应用软件进行管理(比如刷新缓存值以更新数据库),这无疑增加了应用的复杂性。
    因此,NoSQL开始出现,用非关系型数据库以键值对存储,它的结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,这样就不会局限于固定的结构,可以减少一些时间和空间的开销,但是他们瓶颈依然是磁盘速度。
    RAMCloud的原理之一是提供一个通用的存储系统,其规模远远超出现有的系统,应用程序开发人员不需要采取特殊的方式(如NoSQL系统)。理想的状态是,RAMCloud提供一个简单的模型,易用、并且有扩展性,并对应用程序的城战不需要做架构上的改变。

7.3 实际案例

    目前一个可行的RAMCloud配置,每台服务器配置24GB的DRAM,这是高性价比的配置。扩展内存会导致成本的急剧增加。2000服务器会配备48TB的存储空间,平均每GB成本65美元。据预测,到2020年,随着DRAM技术的不断完善,激励1PB-10PB配置的RAMCloud时每GB成本仅需6美元。
    RAMCloud已经在实际中有所应用。例如一个大型的网络零售商或航空公司使用RAMCloud的花费在几十万美元。截止2009年8月Facebook所有非图像数据大约有260TB。这可能接近了当今RAMCloud实用的上限。

    像电视频、照片、歌曲等数据还没有大规模应用RAMCloud,然而RAMCloud实际已经可以用在所有在线的数据。随着DRAM技术的不断改进,RAMCloud在未来会更具吸引力。

7.4 号外

     连12306都采用内存计算平台了,或许,基于memory的计算,

中国铁路客户服务中心12306网站选择Pivotal GemFire分布式内存计算平台改造方案,根据系统运行数据记录,在只采用10几台X86服务器实现了以前数十台小型机的余票计算和查询能力,单次查询的最长时间从之前的15秒左右下降到0.2秒以下,缩短了75倍以上。

7.5 DRAM存储系统是未来?

     图灵奖得主Jim Gray很早就提出了“内存将成为硬盘,硬盘将成为磁带”的说法(出自2006年Tim Bray一篇讨论网格计算的博客,2003年的访谈中他已经表达了同样的意思)。2008年Dare Obsanjo在分析Twitter的架构时也看到,类似的新型应用的最大负担是硬盘I/O,因此会倾向于将随机操作都放到RAM里,只将顺序操作留给硬盘。

扩展连接:https://blog.csdn.net/fenghuangdesire/article/details/41075443

PPT

Guess you like

Origin www.cnblogs.com/Robin5/p/11742326.html