• CockRoachDB简介


    概述

    • CockroachDB是一个分布式关系型数据库,主要设计目标是可扩展,强一致和高可靠。

    • 在无人干预情况下, 能以极短的中断时间容忍磁盘、主机、机架甚至整个数据中心的故障。

    • 采用完全去中心化架构, 集群中各个节点的地位完全对等。

    • 所有功能封装在一个二进制文件中, 可以做到尽量不依赖盘配置文件直接部署。

    • 对外提供标准SQL接口,集群中任意节点都可以作为接入节点处理用户的SQL请求。

      • 接入节点把SQL请求转换为KV操作,并且在必要时将该操作发送至其它节点进行处理,完成后将结果返回给客户端。
      • CockroachDB底层将数据组织成有序的Key-Value对形成一个KV map,其中Key和Value均为字节串。
      • KV map逻辑上按照范围被切分成大量的Key空间,每个Key空间称为Range。
      • 每个Range数据由本地KV存储引擎(RocksDB,LevelDB的变体)存储。
      • 每个Range被复制多份分布到多个CockroachDB节点上,Range副本数量可配置。
      • 每个Range默认大小为64M,合理的Range大小有利于加速节点故障恢复和扩容,及均衡读写负载
      • Range大小应该根据系统压力进行设置,以便管理更多Range。
    • 支持水平扩展

      • 添加更多节点可以提升整个集群的存储容量, 理论上最大可以支撑4EB的数据存储
      • 客户端的查询请求可以发送到集群任意节点, 且每个查询可独立并发执行, 集群的吞吐能力可以随着节点数的增加线性提升
      • 查询以分布式任务的方式在各个数据节点并发执行,可以通过增加节点数来提升单个查询的性能。
    • 支持强一致性

      • Range的多个副本之间使用Raft一致性协议, 所有一致性状态都存储在RocksDB中。
      • 对同一个Range内数据的单一或批量修改, 由Raft保证Range操作的ACID语义。
      • 涉及多个Range的操作, CockroachDB使用高效的无锁分布式事务保障ACID语义。
    • 支持高可用

      • 将Range副本分布在一个数据中心, 可以确保低延迟复制, 同时能容忍磁盘或机器故障。
      • 如果将副本分布在不同机架, 即使某些网络交换机故障, CockroachDB仍可提供服务。
      • Range副本可以跨数据中心和跨地域分布, 以应对来自数据中心电源中断或网络中断, 以及区域电力故障等问题。
    • 隔离级别

      • 基于历史快照时间和当前时间, 提供外部一致的无锁读写。

      • 快照隔离(SI) [Snapshot Ioslation]

        • SI提供无锁读写, 但是存在写偏序问题(write skew)
      • 串行快照隔离(SSI) [Serializable Snapshot Isolation]

        • SSI消除了写偏序, 但在竞争激烈的系统中会存在性能问题
      • SSI是默认的隔离级别, 用户须根据实际性能情况, 选择合适的隔离级别。CockroachDB只提供有限的linearizability(严格的顺序一致性)。

    架构

    • 架构图

      https://mmbiz.qpic.cn/mmbiz_png/xoB0BH4icmV6icxM7fcAVlrr4vmSrbkhELibFV2iah3sCOxGzjpa1BYNDPAaEuEkeZDhgun9wxRe45H0cgwey54ZIQ/0?wx_fmt=png

    • 采用分层架构

    • SQL层

      • CockroachDB支持标准SQL, 当CockroachDB集群的某个节点收到SQL请求时,会经过SQL解析、SQL执行计划生成、SQL执行等重要步骤。
      • CockroachDB兼容PostgreSQL协议,对于报文的封装和解析完全按照PostgreSQL的方式进行,所以用户可以直接使用PostgreSQL的客户端访问CockroachDB。
      • CockroachDB对于用户的SQL语句按照PostgreSQL的语法进行解析,解析完成后生成抽象语法树(AST)
      • CockroachDB 会根据不同的语法树生成对应的执行计划。目前执行计划基本是基于规则的方式来生成的。
        • 对于OLAP的SQL Statement, CockroachDB会将逻辑计划转化为物理执行计划,即通过分布式任务的方式进行并行执行。
      • 当执行计划生成完毕后,CockroachDB会按照约定的方式开始执行,此时CockroachDB将调用事务性的KV接口。执行完成后通过协议层将执行结果返回给客户端。
    • 分布式KV存储

      • 负责Range路由寻址,提供统一的key-value存储。

      • 可以由任意数量的CockroachDB物理节点组成,每个节点包含一个或多个Store(通常一个Store独占一块磁盘)

      • 每个Store包含多个Range,Range为KV层数据管理的最小单元,每个Range的多个副本之间使用Raft协议进行同步

      • Range示意图

        img

        • 这个其实可以类比下hdfs的分片和elasticSearch的分片, 思想上都是相似的。
        • 节点和Range可以根据不同的物理网络拓扑结构进行编排,从而在可靠性和性能之间折衷。
        • 假设一个Range包含三个副本,每个副本可以位于不同的位置:
          • 如果副本分布于同一台服务器上的多块磁盘,可以容忍单块磁盘故障。
          • 如果副本分布于同一机架上的不同服务器,可以容忍单台服务器故障。
          • 如果副本分布于同一个数据中心不同机架,可以容忍单个机架电源和网络故障。
          • 如果副本分布于不同数据中心,可以容忍大规模网络中断或断电。

    关键字

    • CockroachDB key可以是任意字节数组

    • key有两种类型:系统表key和用户表key

      • 系统表key被CockroachDB用于内部数据结构和元数据。用户表key包含用户表数据(以及索引数据)
      • 系统表key和用户表key通过前缀区分,并保证系统表key始终小于用户表key
    • 系统表key有以下几种类型:

      • Global key存储集群级别的数据,例如“meta1”和“meta2” ,以及系统级别的key,例如节点和Store 的ID标识。
      • Store local key用于标识该Store的本地元数据(例如,StoreIdent结构),该部分元数据与所处Store生命周期相关,因此无需复制,即不会通过Raft同步到其它Store。
      • Range local key存储Range的元数据,并与Global key(实际存储层的全局Key)相关联。Range local key由一个特殊前缀,加Global key及一个特殊后缀组成。例如,事务记录是Range local key,形如: x01ktxn-
      • Replicated Range ID local key存储Range元数据(RangeDescriptor),该元数据包含Range所有副本的元信息,这些元数据的变更会通过Raft同步。例如Range lease状态和事务的abort缓存记录。
      • Unreplicated Range ID local key存储该Range副本的元数据,例如Raft状态机的状态信息以及持久化后的Raft日志。
    • 用户表key用于存储所有非系统数据

    多版本数据

    • CockroachDB维护了数据的历史版本,版本之间通过事务的提交时间戳区分。

    • 指定快照时间可以读取此时间戳之前的最新版本数据。

    • 所有版本都有一个最小有效期,当系统进行compaction时,过期的版本数据会被系统回收。

    • 为了防止长时间数据扫描(例如MapReduce)中历史数据被清理,用户也可自行指定数据有效期。

    • 通过RocksDB存储每个key的提交时间戳和GC有效期,支持多版本数据。

    无锁分布式事务

    • CockroachDB提供无锁分布式事务
    • 支持的两种事务隔离界别
      • 快照隔离级别(SI)
        • 隔离级别实现简单,性能较好, 但是存在write skew 问题。
      • 串行化快照隔离级别(SSI)
        • 实现上稍微复杂一些, 但仍然能保证较高性能 (读写冲突严重的情况下稍弱), 但是不存在write skew问题。
    • 默认使用SSI隔离级别
      • 在对性能要求较高,并且没有write skew的情况下可使用SI隔离级别。
      • 在冲突较少的情况下,SSI和SI性能相当,不需要加锁或额外写操作。
      • 在冲突激烈的情况下,SSI仍然不需要加锁,但是会有更多事务被终止。
      • 在任何长事务场景中,SI和SSI都能防止事务饿死。
      • SI和SSI之间的核心区别在于事务提交时SI允许事务的候选时间戳变大,而SSI不允许
    • SI和SSI都要求缓存该Range上发生的读操作结果
      • 如果写操作时间戳比最近一次读操作时间戳要小, 则写操作失败。
      • 每个Range都有一个缓存 (timestamp cache), 保存该Range中key被读取的最新时间戳。
      • 读操作会更新相应的timestamp cache, 部分写操作 (例如Range删除) 也会更新timestamp cache。
        • timestamp cache中最老时间戳会被优先剔除。
    • 每一个CockroachDB事务开始时都会分配一个随机优先级和一个“候选时间戳”。
      • 候选时间戳是接收事务请求时节点分配的本地当前时间戳 (HLC), 作为事务提交的临时时间戳。
      • 如果没有事务冲突,在事务完成所有操作后,该时间戳会成为事务的最终提交时间戳。
    • 在跨多个节点的分布式事务执行过程中, 候选时间戳可能会变大, 但不会回退。
  • 相关阅读:
    常用函数
    PostgreSql那点事(文件读取写入、命令执行的办法)
    如何检测Windows中的横向渗透攻击
    小米笔记本pro版bios经常找不到硬盘
    grunt教程
    nodejs廖雪峰大神教程
    ClickOnce是什么?如何使用?
    asp.net中的ORA-12154: TNS: 无法解析指定的连接标识符
    未能加载文件或程序集 ICSharpCode.SharpZipLib
    PL/SQL 循环
  • 原文地址:https://www.cnblogs.com/ronnieyuan/p/12565977.html
Copyright © 2020-2023  润新知