zoukankan      html  css  js  c++  java
  • HyPer: A Hybrid OLTP&OLAP Main Memory Database System Based on Virtual Memory Snapshots

    HyPer也是内存数据库

    传统数据库基本都是TP,后续出现BI的需求,即AP的需求,传统数据库满足不了

    所以出现了数仓,但是需要ETL把TP的数据同步到数仓中,进行AP

    哪怕基于列存的实时数仓,也要针对Tp和AP用不同的存储引擎

    总之如果要用一套数据结构和系统同时支持TP和AP,之前是没有能做到的

    Hyper说,如果用基于内存的数据库架构,就可以做到

    可以看到虽然都是在做内存数据库,但是针对的问题是不一样的,比如Hekaton,目的是要让TP快100倍

    他们的共同点,是都认为,以当前硬件的发展,应用的核心数据已经完全是可以在内存里面放下了,paper还以Amazon为例算了一下

    这里提到另外一个内存数据库, H-store,是MIT的石破天搞的,商业化后,叫做VoltDB

    但是VoltDB也是主要针对TP的

    架构

    首先Hyper的目的,就是让TP和AP都可以跑在一个内存数据库中

    可以通过配置,是行存还是列存

    只是用主存,而没有使用虚拟内存,因为OS swap会让性能变的很差

    首先,TP

    TP写入使用单线程,这样就没有并发和锁的问题,果然解决问题的最佳方式,是消灭问题。。。

    为什么能用单线程了?因为内存数据库,不像磁盘数据库,瓶颈在IO,所以一定要用多线程去等IO,内存数据库的瓶颈在CPU,那多开线程就是无谓的消耗了

    而且内存数据库非常快,一个tp请求10微妙,就算单线程也足够了

    立马就有个问题,怎么利用多核?作者也想到了,后面会说

    AP

    如何能满足TP的同时,不阻塞AP了,如何解决读写锁的问题

    一般的思路就是snapshot,这里也是这个思路,实现比较骚,直接用系统Fork,Fork出来的子进程会保留和父进程相同的地址空间,这样就做到了读写分离

    这个就是这篇paper的核心的创新,只有一层窗户纸

    fork只能在事务之间做,不能在事务中做,否则事务做了一半,后面无法根据snapshot用Redo恢复

     OS这里会有lazy的copy-on-update,更新只会影响到TP的数据

    那怎么利用多核CPU?

    先看AP,我可以开多个snapshot啊,这样不就是可以同时查多个version

    TP怎么办?

    对于read-only的事务可以并发,利用多核

    那写事务了?

    数据库的数据一般都是可以分partition的,所以对于每个partition的并发是不用加锁的

     如果要跨partition了?那只能用锁了

    可见用单线程的限制还是很强的,虽然这里各种论证合理性,还是不是那么confidence 

    Transaction Semantics And Recovery

    这里事务隔离,主要是通过SI来实现

    那么SI的实现方式,主要有底下几种,

    Roll-back,如果需要读老版本,通过undo roll back回去,Oracle这样做的,这个明显成本很高

    Versioning,MVCC,主流做法

    Shadowing,意思就是写入先写到一个shadow版本,在Transaction提交的时候,再把shadow install回DB,这个方法在乐观并发控制,occ算法就是这么做的;这样就不需要undo,因为如果roll back,直接把shadow丢掉即可

    VM Snapshot,这个就是Hyper用的,

    这里的总结很不错

    还要重点看下的是Durability

    内存数据库,最关键的是,机器crash,数据怎么恢复出来

    依赖Redo,而且这里是逻辑的Redo,一般数据库Redo都是物理的,因为逻辑Redo在事务执行一半的时候,你不知道该怎么恢复,比如Redo,a+1,事务执行一半,你不知道是否加过1
    这里之所以可以用逻辑Redo,因为定期的snapshot的presist,而snapshot一定是事务完成的状态,所以不会有这个问题

    如何保证高可用性?

    通过一个standby节点,standby节点直接通过redo日志来回放

    我们也可以把所有的AP放到standby上去做,分担主的压力

    加入Redo机制,难免会拖累性能

    对于logging的优化,也就两种方法,

    Group,多个Transaction一起提交,这样会加大client的等待时间

    Async,不等log flush到磁盘,当log写入buffer时候就直接commit,会丢数据

    好像很难两全

    上面有一个点,undo日志是只保留在内存中的,

    因为对于Hyper数据恢复的时候,不需要undo,通过snapshot,加上Redo就一定可以恢复,因为不存在事务执行到一半的情况

    所以这里undo只是对于正在执行的Transaction保留在内存中,便于执行一半的事务roll back 

     

  • 相关阅读:
    jQuery index()方法使用
    杂记
    Tp框架代码杂记
    tp U方法的{:U('Index/index',array('id'=>$vo[id]))}
    mb_substr=0,5,'utf-8'
    Thinkphp 超长sql语句编写
    http_build_query()生成url字符串
    html_entity_decode 将数据库里的 | 互联网金融 “野蛮生长” 的休止符| &rdquo转义成”“
    ThinkPHP 左右定界符
    python中unicode和str的组合
  • 原文地址:https://www.cnblogs.com/fxjwind/p/12207354.html
Copyright © 2011-2022 走看看