CockroachDB中一个query是如何执行的?_piriineos的博客-CSDN博客


本站和网页 https://blog.csdn.net/qq_38125183/article/details/81591285 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

CockroachDB中一个query是如何执行的?_piriineos的博客-CSDN博客
CockroachDB中一个query是如何执行的?
piriineos
于 2018-08-11 21:33:30 发布
2348
收藏
分类专栏:
cockroachdb
文章标签:
cockroachdb
query
architecture
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38125183/article/details/81591285
版权
cockroachdb
专栏收录该内容
6 篇文章
1 订阅
订阅专栏
CockroachDB 
CockroachDB架构:
Postgres wire protocol
client和客户端之间用pgsql的协议通信,用户连接由pgwire包的pgwire.v3conn.serve()维持,它负责读取query,将query发给sql.Executor处理,然后收集结果返回给client。
SQL Executor
sql.executor的主要工作是1.解析SQL语句,将解析结果发往后面的模块,然后收集结果返回给pgwire.v3conn。2.协调SQL层其他组成部分,如下面的parser等。3.每个连接都有相应的一个sql.session,包含当前连接的事务的状态,参数的设置等信息,executor也负责更新session的信息。4.对失败的事务(底层传回来的错误信息)进行自动retry,对于不能自动retry的事务通过pgwire传回给client retry,即distSQL返回的result为retry error时:
TiDB的SQL层架构也差不多:
Parsing,executor的调用的第一个模块,负责将SQL字符串转化为AST树,转化规则使用PGSQL的yacc语法。 Logical plan,根据AST树来生成由planNode组成的logical plan,具体的可以看SQL层的文档,planNode中的负责读取数据的scanNode等有rowFetcher方法,主要是用来将SQL request转化成KV request(比如scanRequest查询的key从哪里到哪里),并负责将收集到的KV结果decode,然后转给之后的planNode。 TxnCoornSender,形成的logical plan将发送给Txn sender,这里是一个事务的开始,这个sender会在这个事务中使用的最多的system range里新建一个transaction record,然后不断的异步发送heartbeat来更新record的状态;sender同时也会收集下层传回来的改动过的key或者range,以在commit或者abort事务后异步清理write intent,同时如果有其他事务碰到了这种intent也会在一个heartbeat的时延里来跟txn record确认状态然后进行清理。 txn sender随后将request发送给DistSender。 DistSender,这里可以看成是分布层,主要负责request的分发。request的分发需要读取range元数据信息,range的元数据信息是system range,是两层结构分别是meta1和meta2,有着前缀/0x1和/0x2,因而永远是排在所有的node的range的最前面。meta里的每条KV对都包含一个range的元信息,其中meta1存储的是meta2的元信息,meta2存储的是普通range的元数据,元信息主要包括了该range的最后一个key的值,range的replica分布在哪些node: Range 0 (located on servers dcrama1:8000, dcrama2:8000, dcrama3:8000)
meta1\xff: dcrama1:8000, dcrama2:8000, dcrama3:8000 meta2<lastkey0>: dcrama1:8000, dcrama2:8000, dcrama3:8000 meta2<lastkey1>: dcrama4:8000, dcrama5:8000, dcrama6:8000 meta2\xff: dcrama7:8000, dcrama8:8000, dcrama9:8000 一条元信息为256K,一个range默认64M,可以管理64M/256K一共2^18条元数据,而meta range一共分为两级(meta1只有一个range),因而一共2^36为4EB的数据一个集群可以管理。 meta range跟普通range一样都是默认三个replica分布在cluster中。 分发request需要从meta range中获得replica所在node,一般有两种方法获得node信息,一种是通过range cache,这是一个LRU LIST,保存了最近最多使用的range元信息,不过这些信息有可能不是最新的,因而当在node没有找到目标range时会返回error到这里重新查找,并在LRU中删除对应range元信息;第二个方法在cache中没有找到或者找到的信息发现不正确后使用,即从meta range所在的node中远程读取数据,则从硬盘中读取meta range的数据来进行查找。 获得各个range的位置信息后,根据位置将request各部分分发给各个node,这里由logical plan形成physical plan,每个node自己的request的流程是怎么与其他node的流程相联系的在这里形成,每个node自己的一系列流程称之为flow,node之间通过gRPC传输数据流,一般来讲node间的gRPC连接在flow执行过程中就建立了,如果timeout之后仍然没有flow通过这个连接发送数据那么该连接就会作废,需要注意的是不是每一个flow都会有一个RPC连接,一般是node间有一个连接,每个flow的数据都在这个连接中传输,按序号进行分类,比如下图: 比如三个node一起做join的physical plan: 这里三个node分别读取两个表的数据,然后根据join using的字段将数据流hash到不同的node,这样该字段相同的部分就会在同一node,从而可以做join操作,node间数据流的传输就是通过gRPC。 physical plan形成后需要确定每个range的lease holder是哪一个node,这里通过lease cache来找到replica的lease holder,同样这个cache的信息依然可能不准确,因而sender会依次将前面找出来的replica所在的所有node都发送request,顺序按照为lease的可能性排列,cache中找出来的排在最前面,顺序发送直到接收到成功应答。
Other Node
这里开始事务进行在协调节点之外。
Store,request分发到node后需要确定到底该node的哪一个store包含该range,每个node的内存中都cache了每个store的range信息,通过它可以找到对应store,如果没有找到对应的store,说明之前range cache的元信息是错误的,返回错误到这里重新查找元信息。 确定了store以后开始执行分发的flow,一般来讲flow最开始都是读取数据或者write数据,read或者write在更下层进行,这层提供了一个loop使用方法intentResolver来处理部分下层因为intent冲突返回的retry error,一般是write碰到了timestamp在前的write intent,loop会一直轮询intent的状态是否从pending变为commit或者abort(有些文档说以后可能会加事务等待队列而不是通过轮询,有些文档说已经实现该功能,所以说很操蛋),状态改变后在继续该事务,其他一些不能处理的retry error比如write碰到了刚提交的intent的timestamp较大的情况,则将error一层层向上返回到executor由它控制根据error类型选择push timestamp或者改变priority来retry事务。 Raft,不管flow最开始是read还是write,都需要经过raft。crdb对raft进行了一些改进,主要的是:1.增加了lease holder的概念,并且与tidb不同的是,crdb的lease跟leader是分离的,甚至可以不再同一个node(不过为了减少时延,总是会把lease和leader选在一起)。如果在请求到来时当前没有lease,则该replica就会申请成为lease,过程与leader选举一样,如果group已有lease,则返回一个error并将已知的lease holder同时返回。lease的持续时间存储在一个system table中,每个lease都会定时的heartbeat该table以更新持续时间。通过lease,read可以不再走raft流程,而是就地解决。2.lease的heartbeat不再是每个group都有一个heartbeat,而是node间维持一个heartbeat,这两个node间的group都使用这个连接;此外write的request的可以组成batch来传给follower,然后异步的等待ack,而不是每传一个request就要等follower返回;此外leader的append log跟发送给follower log可以并行执行。3.采用lazy initialization,只有有写入事件时才会激活lease选举,长期没有write会让raft group进入quiet状态,不再进行lease选举。lease在这一层维护一个timestamp cache,记录所有该replica的读操作的timestamp,当有写操作在这一lease时,会检查其timestamp是否小于cache里的,如果小于则会push写操作的timestamp并返回error到executor那里,retry事务。 当lease转变的时候,新的lease生成的timestamp cache可能会因为时钟偏差而小于以前的cache,所以在旧lease过期前的一段时间(timeout-timeoffset),lease将不能读和写。 现在我们回到lease开始处理request时,它会检查当前是否有其他事务正在使用这个lease,如果正在执行的事务跟该事务key的范围重叠,则会将后来的事务的request的放在commandQueue里,等待之前的操作完成。 当轮到该事务request进行时,分为读和写两种类型,读的话直接就在lease将request转化为rocksdb的操作比如puts,gets等,执行完成返回后更新timestamp cache,读在raft中的操作就执行完了;写的话则需要走一遍raft流程,首先检查timestamp cache,看是否有冲突,没有冲突则调用replica.tryAddWriteCmd,这个方法会开始走raft流程,并一直阻塞直到lease的log被apply之后(并不是log commit之后),write的raft流程优化前面讲过,主要是大量request的可以并行发往follower,并且lease和follower的log可以并行append,当group中有多数的follower已经append log后,lease会commit log,并开始apply log。 MVCC Wrapper,这里主要是给rocksdb的get,put等操作加了一个wrapper,用来检测查询的key范围内是否有intent存在,根据intent所在的KV对的timestamp来判断intent造成的冲突是哪一种,如果不影响的则继续进行read或者write,如果有影响的则返回对应错误类型到上层处理。 crdb的文档没有具体讲各种version的数据到底是怎么存储的,不过我觉得应该跟tidb差不多,都是key最后带版本信息,按新版本到旧版本从上到下排列,扫描的时候应该会把key范围内所有版本数据扫出来然后判断每条是否有intent,然后根据每条的timestamp判断intent造成的冲突类型,具体哪几种冲突事务层文档有讲。 在判断完是否有intent冲突后,如果仍然没有返回错误,那么就根据timestamp来读取操作相应版本的数据,crdb是通过使用rocksdb提供的iterator形成当前timestamp的snapshot。 在read或者write后继续执行flow中的其他步骤,当需要node间交换输出时则通过前面说的gRPC的mailbox来传输数据流,数据流的分配一般按hash分流,对于一些特殊情况可能会将该node的数据复制几份全部传给其他node。每个node的flow执行完成后也会通过mailbox将数据传回给gateway node,gateway node收集这些数据直到所有flow都执行完成,这些结果一级级的返回最后到client。  
RocksDB
RocksDB主要包括三类重要结构:
MemTable,分为memtable和immutable memtable,区别是后者不可修改,只可读。memtable的数据结构是skiplist,类似与平衡树的平衡有序结构,但是是基于概率而不需要旋转等操作,每当新操作数据都插入到memtable中,当memtable达到一个界限就会变成immutable,并生成一个新的memtable已供插入。而变成immutable的memtable则由后台线程异步的刷新到level0的sstable中。 Log,主要是为了保证不丢失数据,对于每个memtable都有一个log,在写入memtable前都会先写入log,这样即使崩溃了memtable丢失,再重启时仍然能够恢复memtable。log文件是key无序的,因而每次写入都是顺序写入,不会对写入造成压力。 SSTABLE,用来在硬盘中持久化memtable中存储的KV对。sst是分层级的,从level0到levelN,从底层变成高层level需要进行compaction操作。sst主要分为两部分,一部分是data block,用来存储KV数据,一部分是索引block,存储每个data block最后一个key的值,block的位置以及大小 Manifest,也是一个重要的文件,主要是存储了各个sst的key的范围。 write操作,rocksdb写入很简单,只需要对log的一次顺序磁盘写入和一次logN时间复杂度的内存skiplist插入即可。需要注意的是rocksdb对更新还是删除还是插入,都不会改变原有记录,而是产生一条新的记录,比如删除就产生一条新纪录然后标记为删除,这些记录的回收在compaction时进行,compaction会根据一定的规则回收旧的记录,比如对一条记录进行了更新和删除,那么最后更新记录会被删除,只保留删除记录,不过rocksdb也提供了接口来让用户自己定义compaction filter的规则,crdb的按ttlseconds来回收旧记录应该就是用了这个接口。 read操作,rocksdb的读取要复杂很多,因为数据并不是都在memtable中,很多都写到了sst中,因而按照新鲜度来按顺序查找,顺序从memtable到level0再levelN。当memtable中找不到的时候需要去sst找,从sst找也有快捷的方法,主要是内存中有table cache和block cache,前一个cache存储了sst表名,指向sst文件的指针,指向存储在内存中的这个sst的索引数据以及cache id,通过manifest可以找到key在哪一个sst,然后查找table cache通过索引数据确定是哪一个block以及cache id,这时如果有block cache,那么通过cache id可以直接在其中找到对应block,如果没有则需要硬盘中读取sst然后找到该block。 level0的sst查找跟其他level不同,因为level0是直接memtable导入到硬盘的,因而可能存在key的范围重合的sst,故通过manifest将这些sst都找出来,然后按照新鲜度顺序遍历这些sst。当这个level没找到则继续遍历后续level的sst。 rocksdb中对于事务的处理有两种,一种是严格的带锁的事务,这种在一个事务操作数据时会加锁,另一个事务要操作这些数据时会block住,另一种是乐观的事务,不同事务都能够操作数据,但是在最后提交的时候会进行检查,如果有不同事务操作了数据,那么事务提交就不会成功。 对于crdb我觉得采用的是乐观的事务,因为它本身在raft部分的时候机会检查操作相同key范围的事务,会将其加入到等待队列commandQueue中。 compaction操作主要一个为了将内存中数据保存到硬盘中,一个是减少硬盘的冗余记录,经过compaction的sst将会提高一个level,rocksdb有三种compaction类型:1.universal compaction,这会一次性compaction整个level,然后与下一个level的重合的sst整合。2.level style compaction。3.FIFO compaction。 因为rocksdb这种组织特性,因而它对写入的支持要强于读取,理论的写入性能是40w+/S,而理论的读取性能是6W+/s。
piriineos
关注
关注
点赞
收藏
打赏
评论
CockroachDB中一个query是如何执行的?
CockroachDB CockroachDB架构:Postgres wire protocolclient和客户端之间用pgsql的协议通信,用户连接由pgwire包的pgwire.v3conn.serve()维持,它负责读取query,将query发给sql.Executor处理,然后收集结果返回给client。 SQL Executorsql.execut...
复制链接
扫一扫
专栏目录
PostgreSQL样式解析器从CockroachDB拆分而来-Golang开发
05-26
从CockroachDB中分离出来的Pos​​tgreSQL样式解析器这是从CockroachDB中分离出来的Pos​​tgreSQL样式解析器是什么?参见:复杂SQL格式示例我试图导入github.com/cockroachdb/cockroach/pkg/sql/parser,但是依赖项太复杂了,无法使其正常工作。
为了使事情变得容易,我做了以下事情:复制所有的pkg / sql / parser,pkg / sql / lex并简化依赖关系简化Makefile以仅生成goyacc的东西在解析器和lex中添加goyacc生成的文件以进行获取轻松工作,请参阅.gitignore文件修剪etcd d
docker部署CockroachDB
qq_33332829的博客
10-09
790
什么是CockroachDB
CockroachDB是基于事务性和高度一致的键值存储构建的分布式SQL数据库。它水平缩放; 在磁盘,机器,机架甚至数据中心故障中幸存下来,从而将延迟中断降到最低,并且无需人工干预;支持 高度一致的 ACID交易;并提供了熟悉的 SQL API,用于结构化,操作和查询数据。
docker运行CockroachDB
步骤1: 创建网桥网络
由于将在单个主机上运行多个Do...
评论 1
您还未登录,请先
登录
后发表或查看评论
CockroachDB架构-SQL层
数据源博客
10-08
815
本文知识点来源于官网地址CRDB的SQL层向开发人员公开SQL API,将高级SQL语句转换为底层键值存储的低级读写请求,并传递给事务层。
CockroachDB中的本地与分布式处查询
weixin_33728268的博客
01-12
174
2019独角兽企业重金招聘Python工程师标准>>>
...
Cockroach Design 翻译 ( 六) 混合逻辑时钟、事务执行流程
crownchen的专栏
12-03
4192
7、混合逻辑时钟; 8、事务执行流程;
本地运行flowable_在CockroachDB上运行Flowable
最佳 Java 编程
06-27
105
本地运行flowable
什么是CockroachDB?
CockroachDB是一个我一直关注了很长时间的项目。 这是一个开放源代码的Apache 2许可数据库( Github链接 ),该数据库在很大程度上汲取了Google Spanner白皮书的启发 。 它的核心是可水平扩展的键值存储。 但是,对我们而言真正有趣的是:1)它通过使用Postgres有线协议支持SQL; 2)具有完整的ACI...
CockroachDB架构-复制层
数据源博客
09-26
762
本文知识点来源于官网地址。
CockroachDB架构——概览
数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库优化(Oracle&Mysql&PG&SQL Server )
09-22
767
CockroachDB被设计用于创建开发者想用的源码可用的数据:集扩展性与一致性一体的数据库。开发者经常问到我们是如何实现的,该指南详细说明了CockroachDB进程的内部工作原理。
然而,使用CockroachDB您肯定不需要理解底层架构。这些内容为认真的用户和数据库爱好者提供了一个高级框架来解释底层发生了什么。
一.指南使用
该指南分为多部分来详细说明CockroachDB的每一层。推荐按顺序阅读这些层,以该概览开始,接着阅读SQL层。
如果您正寻找CockroachDB的高级理解,您能只阅读每层的概
CockroachDB架构-存储层
最新发布
数据源博客
10-18
512
本文知识点来源于官网地址。
CockroachDB架构浅析
数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库优化(Oracle&Mysql&PG&SQL Server )
09-18
676
本文源自:http://www.cockroachchina.cn/?p=685
这篇文档介绍和说明了cockroachdb的架构,简单明了。
作为Spanner的开源实现,CockroachDB具有支持标准SQL接口,线性扩展,强一致,高可用等重要特性。总体架构如下图所示:
CockroachDB架构图
总览
Node代表一个CockroachDB进程实例,一般情况下一台物理机部署一个CockroachDB实例,一个CockroachDB实例可以配置多个Store, 单个Store与R...
CockroachDB安装及使用
wsbgmofo的博客
05-11
2944
一,安装1,下载并解压wget -qO- https://binaries.cockroachdb.com/cockroach-v2.0.1.linux-amd64.tgz | tar xvz2,拷贝到系统目录,方便直接通过命令行执行cp -i cockroach-v2.0.1.linux-amd64/cockroach /usr/local/bin二,集群方式启动1,启动第一个节点cockro...
cockroachdb 替换mysql_CockroachDB 源码闲逛 - II (insert a row)
weixin_34921054的博客
01-28
151
前面 3 篇文章更多看事务处理,而事务启停由于语句驱动,本文将看下 CRDB 的启动到收到处理一条简单 SQL 的过程。启动和连接处理CRDB 使用 go 里比较流行的 cobra 来让一个 cockroach binary 具有各种功能 cli,在使用 start 命令启动服务端后代码从这里开始运行。在启动初期就准备好各种日志和 pprof,这里的 pprof 有点意思是支持通过开关控制定期 d...
Pebble 介绍:由 RocksDB 启发,用 Go 编写的 K/V 存储
Go中国
10-09
827
土拨鼠导读:自 CockroachDB 成立以来,一直使用 RocksDB 作为其键值存储引擎。我们选择 RocksDB 是因为其非常符合我们的需求。RocksDB 经过了我们严格的测试...
CockroachDB事务解密(二):事务模型
weixin_33827731的博客
05-31
332
2019独角兽企业重金招聘Python工程师标准>>>
...
cockroachdb 替换mysql_cockroachdb 安装试用(单机伪分布式)
weixin_35785909的博客
01-28
141
1. 下载以下地址,选择对应的操作系统版本即可https://www.cockroachlabs.com/docs/stable/install-cockroachdb.html2. 启动// 启动命令cockroach start --insecure \--host=xxxxx// 提示信息** WARNING: RUNNING IN INSECURE MODE!** - Your clust...
CockroachDB架构——分布层
数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库优化(Oracle&Mysql&PG&SQL Server )
10-10
808
CockroachDB架构的分布层提供了集群数据的统一视图。
--注意:
1)如果您还没有准备好,我们建议先阅读架构概览部分。
一.概览
为了从任何节点访问集群中的所有数据,CockroachDB按照整体排序映射来存储键值对。该键空间描述集群中数据的所有信息及其位置,并将其分为我们称为的"范围",其为连续的键空间块,以便每个键值总是能在单个范围内找到。
CockroachDB实施排序映射以开启:
1)简化查找(Simple lookups):因为我们要鉴别哪个节点复制某部分数据,查询能快速定位其需要的数据.
CockroachDB架构——CockroachDB中的读和写
数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库优化(Oracle&Mysql&PG&SQL Server )
10-19
542
本文解释CockroachDB复制和分布特性如何影响读和写。
本文以总结某些重要的CockroachDB架构概念开始,接着,介绍几个简单的读写场景。
--注意:
1)一个查询通过CockroachDB架构各层的更多细节,请参考分布式事务的生命周期。
一.重要概念
1.集群(Cluster):CockroachDB部署,充当单个逻辑应用。
2.节点(Node):运行CockroachDB的单个机器。多个节点联合一起创建集群。
3.范围(Range):CockroachDB存储所有的用户数据(表,索引等。),
CockroachDB分布式事务解析
piriineos的博客
08-11
2728
事务层
事务层实现了对并发操作的ACID事务支持。
CRDB事务分为两个阶段:
write & reads,即事务执行阶段,当进行写操作时,CRDB并不会直接对硬盘的数据进行修改,而是使用另外两个东西来进行辅助,这两个东西也避免了锁的使用:
Transaction record,存储在range第一个被修改的key处,表明了修改当前key...
cockroachDB学习总结
热门推荐
动次打次
03-02
1万+
1. cockroachDB介绍蟑螂是地球上适应性最强的物种之一。它们能在无氧环境下存活45分钟,在没有食物的情况下存活超过一个月。甚至就算身首异处也无法让小强当场毙命——他们的身体没了头都还能活好几天。
在像 Google,Amazon 和 Facebook 这样的科技巨头内部,掌握领先技术的工程师们也在让他们自己的网站像小强一样顽强。如果一台服务器宕机,一个服务器集群宕机,或者整个数据中心电力
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
©️2022 CSDN
皮肤主题:大白
设计师:CSDN官方博客
返回首页
piriineos
CSDN认证博客专家
CSDN认证企业博客
码龄6年
暂无认证
22
原创
20万+
周排名
113万+
总排名
7万+
访问
等级
928
积分
14
粉丝
28
获赞
评论
87
收藏
私信
关注
热门文章
redo&undo日志解析
21507
Galera replication原理详解
6745
高性能CockroachDB--如何获得更好的性能
5993
MySQL高可用框架--组复制(group replication)搭建测试
4850
CockroachDB集群搭建和配置
3642
分类专栏
c++
1篇
mysql
19篇
linux
1篇
cockroachdb
6篇
最新评论
CockroachDB中一个query是如何执行的?
刘刘刘刘刘刘刘畅:
简直太谢谢楼主写的太好了
EXPLAIN字段详解&测试
tizzybepeacejoy:
感谢分享,建议排排版
mysql复制发展历程(从5.1到8.0版本)
乱键敲死:
不曾想,若是有一天我能像你一样写出这么好的博客该多好,欢迎来我的博客指点
EXPLAIN字段详解&测试
码码码码农也挺好的:
感谢分享,建议排排版
MySQL高可用框架--组复制(group replication)搭建测试
英雄史诗:
1.节点切换对应用不透明。这个是指对外服务ip切换了但应用层不知道吗?这个需要借助keepalived实现吧。
2.一个是断开连接的节点重新连接后不会自动加入节点。需要哪些人工操作呢?
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
InnoDB MVCC解析
CockroachDB集群搭建和配置
CockroachDB分布式事务解析
2019年1篇
2018年27篇
目录
目录
分类专栏
c++
1篇
mysql
19篇
linux
1篇
cockroachdb
6篇
目录
评论 1
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
打赏作者
piriineos
你的鼓励将是我创作的最大动力
¥2
¥4
¥6
¥10
¥20
输入1-500的整数
余额支付
(余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付
您的余额不足,请更换扫码支付或充值
打赏作者
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。
余额充值