tikv总结(个人)

4个协议:

事务层(普通、分布式)

mvcc

raft

coprocessor

其他知识点

持久化写入、读取。

leader选举。

rocksdb用的是lsm tree引擎,增删改都是添加数据,删除就是添加一个delete操作。

1.持久化写入

写入memtable(然后预写入wal),write buffer_size一定量的时候,memtable转成immutable memtable,1个immutable memtable就可以落盘了,到write stall个后会让memtable写入限速。

2.持久化查询

Block cache中缓存着最近最常读的数据

Block cache——memtable——immutable memtable——level0——level1.。。。。。。。。

找key数据的时候,每个sst文件会给出最大值和最小值如果key在次中,就二分法继续找,不在就下一个文件。

 

每个文件都有bloom filter(过滤器),如果它说这个key不在这个文件里,那key肯定不在里面,如果说在,那不一定在里面。

3.簇列(cf

每个cf有自己的block cache、memtable、immutable memtable、sst。多个cf共享几个wal(默认3个)

不同的cf存不同的一张表或者几张表。

4.事务

 

基础事务

事务的存储流程。

Begin

<3,xxx>——<3,frank>

Commit;

1.新begin,然后从pd中获得时间戳TSO,也就是start_ts

2.把修改的数据读取出来,读到tidb server的内存中,内存中先修改,

3.commit进行两阶段提交

一阶段:prewrite:内存中修改的数据写入到tikv节点中,然后将锁信息写入到tikv中。

:key+tso+value(3_100,frank)写信息存到default的cf中,update和delete只放新值。给修改的第一行的key加个主锁,锁信息放到lock的cf中   <3,(W,pk,3,100……)>    3是key,W是写锁 ,pk表示主锁,key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

二阶段:commit:pd组件中要时间TSO(commit_ts),还会写个提交信息

:pd获取时间commit_ts,在write的cf中写入信息<3_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入3,(D,pk,3,100……)  D表示锁被删了。

锁信息在内存中,不写到tikv节点中,别人感知不到锁,就是乐观事务

锁信息提前从内存中写入tikv节点,别人也能在commit前感知到锁,就是悲观事务

先到write的cf中看,最近一次修改时间,拿着key+start_ts到default的cf中找到value。

如果在write的cf中没看到值,但是lock的cf中有,那就不能读(不能读最新的值,可以读老的,也就是mvcc功能)

如果数据小于255字节,会直接存储到writecf中,大于255字节就是正常写到defaultcf或者自己指定的cf

分布式事务流程(数据在多个tikv

Begin

<1,tom>——<1,jack>

<2,andy>——<2,candy>

Commit;

1.只写新值进去。<1,tom>——<1,jack>只写<1,jack>

2.只有第一行需要加主锁,后面的都是指向锁。

3.updatedelete只放新值(putdel

两行数据放在不同的tikv node上。

1.新begin,然后从pd中获得时间戳TSO,也就是start_ts

2.把修改的数据读取出来,读到tidb server的内存中,内存中先修改,

3.commit进行两阶段提交

一阶段:prewrite(预写):内存中修改的数据写入到tikv节点中,然后将锁信息写入到tikv中。

第一行<1,jack>(放在tikv node1中):

key+tso+value(1_100,jack)写信息存到default的cf中,update和delete只放新值。给修改的第一行的key加个主锁,锁信息放到lock的cf中   <1,(W,pk,1,100……)>,1是key,W是写锁 ,pk表示主锁,key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

第二行<2,candy>(放在tikv node2中):

key+tso+value(2_100,candy)写信息存到default的cf中,update和delete只放新值。给修改的第二行的key加个锁指向,锁信息放到lock的cf中   <2,(W,@1,2,100……)> ,2是key,W是写锁 ,@1表示锁的指向,指向key1,2表示key,100是事务开始时间start_ts,后面的不加锁,依附于第一行。

二阶段:commit(提交):pd组件中要时间TSO(commit_ts),还会写个提交信息

第一行:

pd获取时间commit_ts,在write的cf中写入信息<1_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入1,(D,pk,1,100……)  D表示锁被删了。

第二行:

write的cf中写入信息<2_110,100> key+start_ts+commit_ts。再做个锁清理,在lock的cf中插入2,(D,@1,2,100……)  D表示锁被删了。

Tso 120时间 

看tikv node1的write的cf,看结束时间离120最近的是110,然后开始时间是100,再到default里找value。

2节点一样。

原子性:

如果tikv node1提交了,tikv node2没提交,并且tikv node2宕了。

读取,发现tikv node2的write的cf中没数据,发现lock中有个指向1的锁,然后去node1的lock的cf发现锁已经被删了。在node2的write中补上<2,110_100>,在lock中补上<2,(D,@1,2,100……)>

简单来说:宕了起来后,default中的key和value(数据还在)还在,从1中找到锁的记录,回到2补全commit的二阶段。

5.MVCC(多版本并发控制)

本质就是查不到最新的可以查到老的数据。写会造成堵塞

TSO120的时候

读取key=1,2,4

1  jack

2  candy

4  tony

事务1完成,事务2未提交,所以读在write里读到的就是上面的值。

假设全部是悲观事务。即使没commit,别人也能感觉到锁。可见图中lock的cf。

假设当前TSO=120

Key=1

想读

在write的cf中读 key(1)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(1)去default的cf找value(jack),成功获取值。

想写

在write的cf中读key(1)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),

拿着开始时间(100)和key(1)去lock的cf找到锁<1,(W,pk,1,115,…..)> ,发现lock中的start_ts(115)大于write的cf中的put<1_110,100>的100,所以有锁且没提交,不能写,造成堵塞。

Key=2

想读

在write的cf中读 key(2)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(2)去default的cf找value(candy),成功获取值。

想写

在write的cf中读key(2)离当前时间(120)最近的commit_ts110的行,获取到了start_ts(100),拿着开始时间(100)和key(2)去lock的cf找锁,没发现锁,能写,不造成堵塞。

Key=4

想读

在write的cf中读 key(4)离当前时间(120)最近的commit_ts90的行,获取到了start_ts(80),拿着开始时间(80)和key(4)去default的cf找value(tony),成功获取值。

想写

在write的cf中读key(4)离当前时间(120)最近的commit_ts90的行,获取到了start_ts(80),拿着开始时间(80)和key(4)去lock的cf找到锁<4,(W,@1,115,…..)> ,根据@1去找到key=1的锁,发现有锁存在,所以有锁且没提交,不能写,造成堵塞。

6.raft

组成:

一个region(leader)有2个副本region(follower),只有leader角色才能读写,follower不能读写。

follower长时间收不到统治信息,状态会变成candidate,候选者,然后投票选择新的leader。

复制

1.propose操作

请求更改成日志,写入日志

1_1,log{put key=1,name=tom}

2.append操作

Rocksdb raft接收到了日志,并且持久化到了raft中

3.replicate复制操作

leader的节点的raft的log 复制到其他节点

3.1其他节点接收到日志,持久化到自己的raft中(append操作

4.committed操作(raftcommit)(与事务的commit不一样)

其他节点持久化完日志后,会返回响应值(我已经把raft log存起来了),超过一半节点返回响应,就算整个写操作commit了。(多数节点都收到了)

5.apply操作

从rocksdb raft写入到rocksdb kv。

7.raft leader 选举

概念:

term为一段时间关系。(阶段1,阶段2,阶段3,………..)

election timeout  长时间没有leader的时间(无主之地,群雄逐鹿时间

hertbeat time interval 就是follower节点没收到来自leader的统治信息的时间(造反时间

rardom  多节点时间差不多的情况,每个节点都会从rardom——election timeout范围中随机选个时间值进阶(上帝掷骰时间

一步快步步快,先成为candidate(候选者),大概率就会成为leader

投票都是包含自己的一票的

初始状态选举leader的规则:

初始状态,节点都是follower,在term1中,时间超过election timeout,没有leader,哪个节点率先突破election timeout就是candidate(候选者)了。给其他节点发起选举请求,并且进程term2。而其他节点如果发现请求方的term大于自己的,就会同意请求,并且自己也进入下个term。超过一半节点同意就成为leader。

leader宕机情况的选举leader的规则:

hertbeat time interval时间一到,没收到leader的统治信息,谁先到时间,谁就进入下个term,变成candidate(候选者),然后通过选举,成为新的leader。

初始同时进阶情况的选举leader的规则(特殊):

 多节点时间差不多的情况,每个节点都会从rardom——election time out范围中随机选个时间值进阶,降低重复概率。

election timeout(群雄逐鹿时间)和hertbeat time interval(造反时间),2个时间为ticks个数,而ticks时间单位为raft-base-tick-interval(可调)

8.tikv的数据读写

tikv数据写入

客户发起commit完整流程:

1.propose操作

raftstore pool收到写请求,请求转化成raft log。

2.append操作

将raft log持久化到rocksdb raft中,本机持久化完成

3.replicate复制操作

将raft log复制到其他节点的raftstore pool中

-3.1其他节点接收到日志,持久化到自己的raft中(append操作)

其他节点的raftstore pool收到raft log后,将raft log持久化到本地的rocksdb raft中

4.committed操作(raftcommit)(与事务的commit不一样)

其他节点持久化完raft log后返回完成信息,半数(包含leader自己)以上节点返回完成信息后committed动作完成。

5.apply操作

rafstore pool把raft log读出来,写给apply pool,apply pool拿着raft log,写到rocksdb kv中。

tikv的数据ReadIndex读取

Raft commit:写进rocksdb raft中了

apply:写进rocksdb kv中了

在10:00时1-95、1-96都写进raft了

在10:05时想读1-95,但是1-95还在raft中,kv只到1-93,并记录下了挡球写进raft的1-97为readindex

在10:08时终于1-95写进kv中了,但是前面的读请求还在等待

在10:09时,readindex 97也写进kv了,此时1-95必定写进kv了,所以可读。

tikv的数据lease读取

在开始到election timeout(造反时间)这段时间内,leader不变。

tikv的数据follower读取

leader

follower

在follower读取,在leader写入95,follower向leader要commitindex(比如97,那follower这边要apply到97才能读想要的95。

9.coprocessor(协同处理器)

算子下推:

不一定要从tikv中读出出来,到tidb server中做过滤,

可以在每个tikv节点中过滤自己节点中的数据。然后再tidb server进行校验。

表扫、索引扫、过滤、limit求最大最小值、聚合、统计信息、采样 等等

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪灵骅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值