转自:http://blog.csdn.net/ransom0512/article/details/50440316


简介

VoltDB数据库是一个分布式,可扩展,shared-nothing的内存数据库。使用Java 写的存储过程来定义事务。使用标准SQL访问数据,使用并行的单线程处理方式确保数据一致性,同时避免了传统数据库的锁,插销,资源管理开销。 
VoltDB具有如下特点:

  • 高吞吐量:百万次每秒
  • 横向拓展:可以根据需求自由拓展,性能线性增长。
  • 高可用性:数据支持副本、也可以持久化保存、除此之外,还支持双活机制。
  • 实时数据分析:数据实时性高,因为都是内存计算。
  • 完整ACID支持,保证事务性和可靠性。

VoltDB的设计动机来源于内存成本的大幅下降,系统对于数据的时效性要求越来越高,而传统数据库由于数据在本地文件保存,所以不论并发还是处理速度,都难以满足要求。而新型的NoSQL数据库,又缺乏SQL支持以及完整的ACID的支持,完全无法提单传统数据库。 
VoltDB、NoSQL和传统关系型数据库的对比如下所示: 

设计思路

高吞吐量、实时性

VoltDB通过对传统数据库进行分析,发现数据只有12%的CPU时间在做真正有意义的数据操作,而其他绝大部分时间都被缓存,并发控制等步骤消耗了。

  • 索引管理(Index Management):数据库的索引一般是基于B树的,这些索引会显著消耗IO和CPU。
  • 日志(Logging):传统数据库一般会写两次日志,一个是数据库数据存储部分,一个是数据库恢复日志,而且这些操作都必须强制性刷到磁盘上去,这就带来显著的IO消耗。
  • 锁(Locking):数据的读写操作都会涉及到锁,这是一个十分频繁的操作。
  • 锁管理器(Latching):全局共享的数据比如索引数据,表元数据,资源信息等,都必须保障多线程环境下的可靠运行,所以这种锁管理器无疑会消耗更多的CPU资源。
  • 缓存管理(Buffer Management):数据存储在固定大小的磁盘页中,缓冲池则管理着这些磁盘页,这些都会来言密集的IO操作。

综上,有88%的CPU时间都浪费在这些对于实际操作无意义的步骤上去了,要提升数据库性能,只有从根本上减少这种冗余的步骤,集中进行数据运算,才能完全利用CPU。 
VoltDB通过内存存储、数据分区和无锁计算来实现高性能运算。

  • 内存存储 
    VoltDB所有数据都保存在内存中(可靠性中会有数据刷到磁盘,见VoltDB ACID中可靠性设计), 内存存取速度已经比磁盘远远高出几个数量级了,这就是VoltDB高性能的重要原因。
  • 数据分区 
    VoltDB对每个节点的内存进行管理,在每个节点上创建多个分区,所有分区表中的数据,都分散在各个分区中,然后在读写的时候,就可以实现多个分区并发进行,所以拓展性是线性提升的。 
    这种分区机制也会带来问题,当集群需要扩容的时候,需要停止整个集群,然后再进行扩容;当集群启动的时候,VoltDB会重新调整数据分布,在所有数据分布调整完毕之后,才开始提供服务。
  • 无锁计算 
    VoltDB数据分区存放,在执行SQL语句的时候,客户端就会根据条件自动判断数据在哪个分区中,然后下发至该分区执行。如果查询条件中不包含分区列,那么就会由客户端进行统一控制,在每个分区上都进行查询之后,再统一返回结果,这种场景会极大影响性能。 
    VoltDB的程序都是以存储过程的方式执行的,支持使用java或者其他语言定义存储过程。每个分区的存储过程执行都是单线程线性执行的,这就保证了单分区的无锁设计。当一个语句涉及到多个区分协调读写的时候,VoltDB会在协调,统一锁定分区队列,等该语句执行完毕之后,才会释放锁。所以多分区操作才会如此消耗性能。 
    VoltDB在分区管理上,建议每个物理CPU创建一个分区,这样单个分区内的数据都在CPU的一级缓存和二级缓存上,避免在多个CPU之间的数据操作,最大限度的提升CPU利用率,避免并发锁。所以理论上,VoltDB的CPU使用率是可以达到100%的。

横向拓展

VoltDB多分区设计,使得数据分散在各个分区中,每个分区可以提供并发访问,既提升了性能,也达到了无锁的效果。所以理论上,VoltDB的横向拓展可以使得性能得到线性提升。

高可用性

VoltDB使用K-safety、双活、snapshot、WAL机制组合机制保证数据的高可用性。

  • K-Safety 
    其实就是N+1的副本机制,VoltDB在写数据操作的时候,会在每个副本中执行该语句,这样就可以保证数据被正确插入每个副本。这N+1的副本都可以同时提供访问,同时允许最多N个副本丢失(分区故障), 当N+1个副本都不可用的时候,VoltDB就会停止服务进行修复。
  • 双活 
    多集群双活机制,两个集群都可以提供服务,数据在多分区之间异步复制,当一个集群挂了的时候,另外一个集群提供服务,当异常集群恢复之后,会自动进行数据同步,只有数据一致的时候,才会提供服务。但是这种机制其实还是有问题,有可能导致数据不一致,因此同步复制机制还是需要的。
  • Snapshot 
    由于数据在内存中存放,当节点掉电的时候,数据就会丢失,所以VoltDB会定期对每个分区数据做快照,以备节点掉电时候进行恢复。
  • WAL 
    Write ahead log,VoltDB会在对数据进行插入操作的时候,预先进行写日志操作,这个和传统数据库一样,但是由于是顺序写入,所以性能还是比传统数据库要好很多。 
    Snapshot机制和WAL机制会导致造成性能5%左右的下降,不过这个也是为了完整ACID不得不做出的牺牲。

性能

VoltDB 宣称具备非常高的可伸缩性,超过 120 个分区、39台服务器,可在 300 个 CPU 核心上每秒钟处理 160 万的复杂事务

VoltDB在资料中有一个和数据库进行的性能对比,结果如下: 
Dell R610, 2x 2.66Ghz Quad-Core Xeon 5550 with 12x 4GB (48GB) DDR3-1333 Registered ECC DIMMs, 3x 72GB 15K RPM 2.5in Enterprise SAS 6GBPS Drives 

License

License为AGPL,该许可比GPL要求更加严格,产品即使以WEB的方式发布了,也必须公开源代码。在使用的时候需要小心。

VoltDB介绍——本质:数据保存在内存,充分利用CPU,单线程去锁,底层数据结构未知的更多相关文章

  1. java 读取文件——按照行取出(使用BufferedReader和一次将数据保存到内存两种实现方式)

    1.实现目标 读取文件,将文件中的数据一行行的取出. 2.代码实现 1).方式1: 通过BufferedReader的readLine()方法. /** * 功能:Java读取txt文件的内容 步骤: ...

  2. 【学习总结】iOS 数据保存几种方式总结

    在iOS开发过程中,不管是做什么应用,都会碰到数据保存的问题.将数据保存到本地,能够让程序的运行更加流畅,不会出现让人厌恶的菊花形状,使得用户体验更好.下面介绍一下数据保存的方式: NSKeyedAr ...

  3. [源码]解析 SynchronousQueue 上界,下界.. 数据保存和数据传递. 堵塞队列. 有无频繁await?

     简析SynchronousQueue.LinkedBlockingQueue(两个locker,更快),ArrayBlockingQueue(一个locker,读写都竞争)     三者都是bloc ...

  4. YARN的内存和CPU配置

    时间 2015-06-05 00:00:00  JavaChen's Blog 原文  http://blog.javachen.com/2015/06/05/yarn-memory-and-cpu- ...

  5. 转载-YARN的内存和CPU配置

    Hadoop YARN同时支持内存和CPU两种资源的调度,本文介绍如何配置YARN对内存和CPU的使用. YARN作为一个资源调度器,应该考虑到集群里面每一台机子的计算资源,然后根据applicati ...

  6. GDAL 遥感图像处理后的数据保存为图像文件的实现方法

    在遥感图像处理中,GDAL库不仅能读取和处理大部分的遥感图像数据,而且还能够实现图像处理后将数据保存为图像的功能. 本文就详细介绍如何将内存中的图像数据保存为.tif格式. 首先,遥感数据处理完,保存 ...

  7. Java API —— IO流(数据操作流 & 内存操作流 & 打印流 & 标准输入输出流 & 随机访问流 & 合并流 & 序列化流 & Properties & NIO)

    1.操作基本数据类型的流     1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出 ...

  8. Android数据保存之文件保存

    前言: 上一篇文章写了在Android中利用SharedPreferences保存数据,SharedPreferences在保存数据的时候主要是保存一些应用程序的设置信息或者少量的用户信息,并且是以k ...

  9. Android数据保存之SharedPreference

    前言: 程序中处理的大部分问题都与数据有关,读取数据显示在UI上,读取的数据可以是本地的,也可以是网络的.保存用户数据到存储空间,可以是本地的数据库,文件等,也可以是保存到网络服务器.总之大部分的程序 ...

随机推荐

  1. ironpython 2.75 在c#中的使用

    ironpython的介绍请自行搜索. 一句话,python是一个类似lua js的动态预言.ironpython是在net环境执行python的类库. 效果:在网站中调用一个python文件test ...

  2. JAVA运算符和优先级

    1.算术运算符: ++ 和 -- 既可以出现在操作数的左边,也可以出现在右边,但结果是不同,如: ①int a=5: int b=a++: #先把a赋给b,a再自增 ②int a=5: int b=+ ...

  3. poj 2954 Triangle(Pick定理)

    链接:http://poj.org/problem?id=2954 Triangle Time Limit: 1000MS   Memory Limit: 65536K Total Submissio ...

  4. Object-C : Block的实现方式

    摘自:http://www.cnblogs.com/GarveyCalvin/p/4204167.html> Date : 2015-12-4 前言:我们可以把Block当作一个闭包函数,它可以 ...

  5. Eclipse 高亮显示选中的相同变量

    问题描述: 在 eclipse 中使用快捷键或其他原因,不小心按错了,使得变量的高亮显示没了. 1.网友解决方法:  选择:windows-> preferences->java-> ...

  6. ubuntu12.04 gdb安装使用

    参考文档:http://blog.csdn.net/haoel/article/details/2879 http://www.programlife.net/gdb-manual.html [新手笔 ...

  7. iOS - Swift 基本语法

    前言 Swift 全面支持 Unicode 符号. Swift 中的定义和实现是在同一个单元中的,通常一个 Swift 源代码单文件是以 ".Swift" 结尾的. Swift 不 ...

  8. iOS - Socket 网络套接字

    1.Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket.Socket 又称 "套接字",应用程序通常通过 "套接字& ...

  9. 关于Java控制台输入输出乱码问题

    产生原因:因为这个开源项目的默认字符编码为UTF-8,所以我的控制台的字符编码也自动变成了UTF-8,而键盘的输入流的默认格式是GBK格式,这样就造成了在GBK转UTF-8的过程中产生的奇数乱码错误( ...

  10. linux学习笔记2-命令总结2

    权限管理命令  chmod 其他权限管理名  chgrp  chown  umask ========================================================= ...