cockroach官方文档翻译---2.4分布层

2.4 分布层

CockroachDB结构为集群提供了统一的view。

**概要

--monolithic sortedmap结构

--使用monolithic sorted map(庞大的sorted map)

--与其他层的交互

**技术细节和组件

--gRpc

--BatchRequst

--DistSender

--元range KV 结构

--表数据KV结构

--range描述符

--range分裂

**与其他层的交互

--分布层和事务层的交互

--分布层和复制层的交互

2.4.1 概要

  为了保证集群中的所有数据可以被所有节点访问,cockroach数据以KV键值对形式存储庞大的 sorted map中,这些key空间描述了集群中所有数据及其位置,将数据分为ranges。Ranges是key空间临近的chunks,每个key总是被包含在一个range中。

Cockroach实现sorted map 通过:

--简单的查找:节点包涵某一部分数据,query可以快速的定位他们想要的数据

--高效的扫描:定义数据的顺序,通过扫描可以发现数据具体的range。

**Monolithicsorted map 结构

Monolithic sortedmap结构由两个基本的组件组成

--系统数据,包括元ranges 描述了集群中数据的位置(其他的集群范围和本地数据元素)

--用户数据,存储集群的表数据

元ranges

集群所有range的位置,存储在key空间的两个级别的索引中,即元ranges,第一个级别(meta1)指向第二级别,第二级别(meta2)指向集群中的数据。每个节点被告知在哪里定位meta1 range(即range 描述符,具体细节如下)。Range不会被拆分。

  元range结构默认寻址4EB(1EB=1024PB,1PB=1024TB)的数据,可以寻址2^(18+ 18) = 2^36 ranges,每个range寻址 2^26 B,综上, 2^(36+26) B = 2^62 B = 4EB,对于更大的range大小,我们可以在未来扩展它的能力。

元数据与其他正常的range处理相似,像集群中的KV数据的其他元素

一样,被访问和复制。

Meta2 range缓存每个节点的已取过的值,用于优化未来的访问。无论何时一个节发现meta2缓存是无效的,通过在meta2 range上定期的读更新缓存。

表数据

  在集群中节点存储的元数据是KV数据,这个数据被分成64MB的相邻的连续key空间,即ranges。这个大小足够小使节点之间可以快速移动, 也足够大存储有意义的可能被同时访问的连续数据,是一个合适的值。这些ranges在集群中清洗,保证集群的耐受性。

这些range被复制(在复制层),每个复本的地址存储在meta2 range中。

**使用monolithic sorted map(庞大的sorted map)

当节点接受到请求,通过比较请求中元ranges的keys与自己meta2range,查找将请求路由到哪个节点。

这些meta range大量的被缓存,所以很容易获得,不需要向实际meta2 ranges节点发送RPC。

节点将这些KV操作发送给meta2 range的租户。不过有可能发生,当数据移动,节点不再告知请求节点,数据现在存储的位置。这种情况下,将回到meta2 range获取最新信息,再重试。

**与其他层进行交互

与分布层相关联的其他层:

--在相同节点接受来自事务层的请求

--识别哪个节点可以接受请求,将请求发送到正确的复制层节点。

2.4.2 技术细节和组件

**gRPC

gRPC是与其他节点交流的一个软件节点,分布层是与其他节点交流的第一层,Cockroach在这里实现了gRPC

gRpc需要输入输出使用potocol buffers(protobufs)格式化,为租用Grpc,cockroachDB实现了protocol-buffer-based API(基于缓冲协议的API)定义为

api.proto.

更多信息,查看gRpc的官方文档。

https://grpc.io/docs/guides/

gRpc是一个客户端直接调用不同机器的服务端的方法,就像他是个本地客户端,使创建分布式应用和服务更加容易,在很多RPC(remote procedure call,远程过程调用)系统中,gRpc基于定义服务思想,识别方法,该方法可以使用参数被远程调用,并返回类型值。在服务器端,服务器实现这个接口,运行gRpc服务处理客户端调用。在客户端端,客户端具有一个存根提供与服务端同样的方法

GRpc客户端和服务端在不同的环境中彼此可以运行和交流,可以使用java创建一个GRpc的服务端,客户端使用go,python,ruby语言。可以获取最近的google api获得最新的实现。

potocol buffers

https://developers.google.com/protocol-buffers/docs/overview

 

potocol buffers CSDN(非官方文档)

http://blog.csdn.net/manchew/article/details/39494901

 

**batchRequest

所有的KV操作输入protobuf,叫做batchRequest.Batch的目标是被batchRequest头识别,同时是一个请求的事务记录的指针,在其他方面,一个节点使用batchRequest,调用protobuf,获得batchResponse

**DistSender

网关或者合作节点的DistSender接受到来自自己的TxnCoordSenderbatchRequestDistSender应答,解析batchRequests,并将通过meta2 range将一个新的batchRequests请求集路由到实际包含数据的节点。使用缓存发送请求给租户,也会准备好去尝试其他的副本,按照“邻近”顺序。缓存的副本是租户,租户在副本集list里向前移动,并按顺序向所有副本发送RPC

 请求收到非租户失败,直到副本的最后一个已知租户返回一个失败指针。

网关节点使用明显更新的租约重试请求,不会到达客户端。所有的节点开始依赖于这些命令,DistSender收集准备结果返回给客户端。

**元range KV结构

像集群中的其他数据一样,metarange使用KV键值对构建他的结构,meta range都具有相同的结构

metaX/successorKey ->LeaseholderAddress, [list of other nodes containing data]

元素

描述

metaX

Mata range级别,我们简单使用meta1或者meta2,但是实际在cockroach分别为是\x02\x03

successorKey

第一个比扫描到key更大的key,使cochroachDB的扫描是高效的,简单的扫描keys直到发现一个值更大的key,获取相关数据的位置。对于keyspace的末尾,successorKey即为maxKey

LeaseholderAddress

副本主要负责读写,叫做LeaseholderAddress,复制层更多信息,请查看Leases

例如

meta2/M-> node1:26257, node2:26257, node3:26257

在这种情况下,node1的副本是租户,node2和node3同样包含副本。

在这种情况下,node1的副本是租户,node2和node3同样包含副本。

例如:

想象我们有一个按照字母顺序排序的列,我们使用去查询,metarange数据类似:

1)Meta1 包含存储meta2副本的节点地址

# Points to meta2 range for keys [A-M)

meta1/M -> node1:26257, node2:26257, node3:26257

 

# Points to meta2 range for keys [M-Z]

meta1/maxKey -> node4:26257, node5:26257, node6:26257

2) meta2包含集群中每个range副本的位置,第一个是Leaseholder.

# Contains [A-G)

meta2/G -> node1:26257, node2:26257, node3:26257

 

# Contains [G-M)

meta2/M -> node1:26257, node2:26257, node3:26257

 

#Contains [M-Z)

meta2/Z -> node4:26257, node5:26257, node6:26257

 

#Contains [Z-maxKey)

meta2/maxKey-> node4:26257, node5:26257, node6:26257

**表的数据的KV结构

KV数据,表中数据使用如下结构:

/<tableId>/<index id>/<indexed column values> -><non-indexed/STORING column values>

表本身存储1index_id作为主键列,表中剩下的列为存储/覆盖列。

 

**Range描述

CockroachDB的每个range包含元数据,即range描述符。一个range描述符由如下组成:

--一个时序的rangeID

--range包含的key空间(key)。例如,在表数据的KV结构中,第一个和最后一个<index column values> ,这个决定了meta2 rangekey

--节点的地址包含range的副本,它的leaseholder(负责读写)的第一位置。这决定了meta2 range key的值。

因为range描述比较meta2 rangeKV数据,每个节点的meta2缓存也存储range描述。

Range描述更新:rangeraft成员更改(具体的细节在复制层讨论)—leaseholder改变—range分裂

所有的range描述更新发生在本地range,然后扩散到meta2 range

**range分裂

默认,cockroachDB保存ranges或副本在64MiB中,一旦range达到限制将分裂成232MBranges(由连续的key空间组成)

range分裂,节点创建一个新的raft group与被分裂的range相同的成员。事实上,两个range意味着事务升级到meta2,使用新的表空间边界,使用range描述的节点地址。

2.4.3 与其他层的交互

**分布层与事务层

分布层的DistSender接受到它自己节点的TxnCoordSender发送的BatchRequests

封装在事务层

**分布层与复制层

分布式层路由BatchRequests到包含数据range的节点,最终路由到raft group leader 或者leaseholder,在复制层处理





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值