为提升 TSO 的处理性能针对部分场景 TiDB 引入了 TSO Follower Proxy、RC Read TSO 优化、Local TSO 等特性,通过扩展 PD 处理能力和减少 TSO 请求的方式 TiDB 在事务开始时会获取 TSO 作为 start_ts、提交时获取 TSO 作为 commit_ts,依靠 TSO 实现事务的 MVCC。 Local TSO当通过 enable-local-tso 启用后数据中心内的 PD 会选出一个节点作为 local tso allocator 用于分配 TSO,该节点作为 local tso 分配的 为保证 local tso 和 global tso 的线性增长,global tso allocator 和 local tso allocator 会进行 max_tso 同步:Global tso 如果 max_tso 比自己的大则更新 TSO 为 max_tso,否则直接返回成功。
分布式化 TSO 前文说到,很久以来 PD leader 都是作为一个单点提供 TSO 服务的,但既然有了 Local TSO 这个概念,每一个 DC 都要有一个 Local TSO 的分配者,那我们自然要把 线性一致性 单点 TSO 的大小是全序的,即任意两个 TSO 均可以确定的比较出大小,而任意两个 Local TSO 的大小则不再是全序关系,原因也很简单,这两个 TSO 可能分别来自不同的数据中心,由于只需维持在各自数据中心的一致性 而对于 Global TSO,因为其对应服务的是全局事务,全局事务没有数据访问的约束,也就意味着持有一个 Global TSO,我们需要和之前分配过的所有 Global TSO 以及 Local TSO 以一言蔽之,对于 Local TSO 的改造,PD 把原有的「TSO 由 PD leader 单点分配」这个设计剥离,将 TSO Allocator 的选举以及 Local TSO 分配均变成以数据中心为单位的分布式存在 TSO 和 Global TSO 这三种 TSO,保证每一个 TSO 的全局唯一性。
模型结构的关系 6.扩展 6.1 通过Hotspot源码分析 java volatile 关键字的语意及其与x86-TSO/普通TSO内存模型的关系 6.2 Linux内存屏障宏定义 ---- 6.扩展: 6.1 通过Hotspot源码分析 java volatile 关键字的语意及其与x86-TSO/普通TSO内存模型的关系 Java 的 volatile语意:Hotspot 其实作者注解已经说的很明白,现在大部分RISC的SPARC架构的CPU的实现都满足TSO模型,所以只需要StoreLoad屏障而已 我在新南威尔斯大学的网站上找到了关于TSO的比较正宗的解释: ? 这三点已经十分符合本文的x86-TSO模型。 ,所以缓存可以和主存合并抽象成共享存储 x86-TSO的写操作严格遵循FIFO CPU流水线式地执行指令会使得CPU对接受到的指令流顺序执行 x86-TSO中唯一重排的地方在于StoreBuffer
所以PD 必须是高可用的状态进行工作. 2 PD 对事务的TSO 号进行分配通过本地的时间和逻辑时间来形成一个INT64的全局事务号. 3 分布式数据库中考虑问题需要考虑并发和单位时间事务量的问题, 这里PD 建立TSO 进行了性能优化 , 针对申请进行了时间段的申请, 不是即时分配事务TSO,而是提前申请,将一段时间设置为申请的段,申请后,直接生成TSO,事务在高并发执行是,不会在计算TSO,而是直接给出已经计算好 ,并且在内存中存储的TSO 给申请的事务即可. 4 申请TSO 和获取TSO 也需要时间来沟通,所以这里申请TSO的客户端也不会一次仅申请一个TSO,而是将一组TSO 拿走方便后续使用,提高性能. 其中 上面 1 2 3 4 几个点进行一些详细的解释和说明 这里PD 的工作中有几个重点 1 时间, 时间不准确会导致分配事务的中断和问题 2 缓存, TSO ,一次会批量计算,所以需要更多的内存来支持存储预先计算好的 TSO 3 批量获取TSO ,然后应对并发,这里如果事务回滚,相关的TSO 应该作废,所以如果有大批量的事务回滚是会消耗大量的TSO.
TSO TSO(TCP Segmentation Offload) 是一种利用网卡对大数据包进行分片,从而减小 CPU 负荷的一种技术。 其作用通过两个图来对比: TSO off和GSO off 状态数据包的发送过程: ? TSO on状态数据包的发送过程: ? 一个大的网络包直到进入网卡内部后才由网卡进行了分片。 它比 TSO 更通用,原因在于它不需要硬件的支持就可以进行分片。 其过程是:首先查询网卡是否支持TSO 功能,如果硬件支持TSO则使用网卡的硬件分片能力执行分片;如果网卡不支持 TSO 功能,则将分片的执行,延缓到了将数据推送到网卡的前一刻执行。 网卡关闭TSO时,GSO on状态数据包的发送过程: ? 一个大的网络包直到进入网卡前的最后一步才进行了分片。 TSO和GSO对应数据发送过程,对应数据接收过程的是LRO和GRO。
三种内存一致性模型的比较: TSO内存模型和SC内存模型对比: 执行:所有SC执行都是TSO执行,TSO执行有些不是SC执行,所以SC执行是TSO执行的子集。 可以从以上四个方面比较SC和TSO: 1.可编程性:SC是最直观的。 TSO很接近,因为它对于常见的编程习惯用语就像SC一样。 然而,其他的非SC执行需要加特殊指令。SC略胜TSO。 2.性能:对于简单的cpu,TSO可以提供比SC更好的性能,但是可以通过推测来缩小差异(CPU设计相对更复杂些),TSO优于SC。 3.可移植性:SC被广泛理解,而TSO被广泛采用。 SC优于TSO 4.精确度:SC,TSO和x86-TSO都是被精确定义的。打平。 宽松一致性模型: 1.可编程性:对于那些使用SC的人来说,宽松的模型可编程性是可以接受的。 3.可移植性:宽松一致性模型相对于SC和TSO限制很多,移植相对困难。 4.精确度:许多宽松一致性模型是非正式定义的,精确度差于TSO和SC。
Abbreviated as TSO, TCP segmentation offload is used to reduce the CPU overhead of TCP/IP on fast networks TSO breaks down large groups of data sent over a network into smaller segments that pass through all The NIC must support TSO. TSO is also called large segment offload (LSO).
TSO是使得网络协议栈能够将大块buffer推送至网卡,然后网卡执行分片工作,这样减轻了CPU 的负荷,但TSO需要硬件来实现分片功能; GSO(Generic Segmentation Offload )比TSO更通用,基本思想就是尽可能的推迟数据分片直至发送到网卡驱动之前,如果硬件不支持TSO分段则由dev_hard_start_xmit中的dev_gso_segment先软件分段的segs赋值给skb 命令(ethtool -K eth0 tso|gso off|on)可打开或关闭网卡驱动的gso/tso特性: 1, 物理网卡不支持GSO时, 使用TSO时TCP分段在驱动处调用硬件做,不使用TSO时TCP 3, 物理网卡不支持TSO时,使用GSO时在发送给驱动前一刻做,不使用GSO在TCP层软件做。 TSO与GSO的重要区别 1, TSO只有第一个分片有TCP头和IP头,接着的分段只有IP头。 如果物理网卡不支持TSO将调用skb_gso_segment软件执行GSO。
速查: tso在网卡层面拆包,gro在网卡层面拼包 ethtool -k eth0 generic-receive-offload:ethtool -K eth0 gso on tcp-segmentation-offload :ethtool -K eth0 tso on tcpdump -i eth0 -s 0 -w s3_s.cap port 3001 默认tso:on,gso:on,gro:on 1 mysql 原来在wireshark是在网卡层面以上抓的包,网卡根据tso和gro的配置自动拆/拼包,这两个概念后面介绍 2 TSO 查看参数配置: ethtool -k eth0 | grep -E 'generic-segmentation-offload on # ethtool -K eth0 tso off 为了降低 CPU 的负载,提高网络的出口带宽,TSO 提供一些较大的缓冲区来缓存 TCP 发送的包,然后由网卡负责把缓存的大包拆分成多个小于 tcpdump 或者 wireshare 抓取的是网卡上层的包,所以我们可能会观察到大小超过 MTU 的包 generic-segmentation-offload必须打开后tso才能生效 tso
这技术通常被称做TCP分段卸载(TSO)或者大段卸载(LSO)。 如果不需要完整的TOE功能,可以选择其他网络适配器,这些适配器可以灵活支持TOE的功能子集,如校验与卸载(TSO)或LRO。 TCP报文使用TSO,而UDP报文则使用UFO,都属于LSO的范畴。 TSO (TCP-Segmentation-Offload):将TCP分段工作交由网卡驱动执行,该特性需要网卡硬件支持。 TSO off和GSO off: TSO on: UFO(UDP-Fragmentation-Offload):TSO针对TCP报文分段处理,UFO将对UDP报文进行IP分片的工作交由网卡驱动层处理
问题解决: 在分析问题前,先给出上述问题答案,在10.81.2.92中关闭抓包的网卡的tso和tx功能. ethtool -K eth0 tso off ethtool -K eth0 tx off /tx-checksumming:支持接收/发送方向的IP校验和计算; scatter-gather:用于将一个buffer分割为多个小的部分,是实现tcp-segmentation-offload(TSO )的基础; tcp-segmentation-offload(TSO):也被称为large send offload (LSO),用于将TCP按照实际的mss进行分段发送。 udp-fragmentation-offload(UFO):工作方式与tcp-fragmentation-offload类似; generic-segmentation-offload(GSO):工作方式与TSO :对出去的报文加上vlan tag; TIPS: 类似地,如果抓UDP报文显示校验和等异常时,可以通过ethtool临时关闭UDP offload功能 TSO,UFO,GSO等功能可以提高报文交互能力
首先我们先对percolator的一些概念进行理解,然后在看TIDB 对于这些理论改进的部分. 1 获取TSO 用时间戳作为 start_ts 1 事务在提交需要缓存在client端, percolator 的事务提交分为 perwrite 和 commited 2 事务开启会获取TSO 事务号, TSO 是通过时间戳标识的,事务开启时获取的时间戳是 start_ts 3 Perwrite 过程 3.1 获取TSO 用时间戳作为 start_ts 3.2 选择一个写入点为主节点, 其他的复制节点为从节点 3.3 在获得start_ts后进行判断,要插入的key是否有冲突, 如时间有一致的, perwrite 事务直接abort 3.4 时间戳被记录到数据ROW中 3.5 WRITE 操作进行锁定,此时这个时间只能属于这个操作 4 Commit 过程 4.1 获取TSO 这里有一个位置是需要等待的,就是我们的 get TSO .
pd 会产生全局唯一递增时间戳tso TiDB二阶段提交简图 ? 如果报错为 keylslook和WriteConfict, 都会重新获取tso,重新启动2pc。其他错误则会报错。 如果失败 先执行回滚操作,然后根据错误判断是否重试: lockNotEXist重新获取tso作为start_ts 启动2pc提交。 这几步操作,我简单描述一下 在tidb开始写key的操作,如果遇到锁相关的错误,都会进行一个重新获取tso,重新启动2pc的提交。 TiKV二阶段提交简图 ? 总结,在二阶段提交中 PD 提供:提供全局唯一递增时间戳 tso发放。管理 raft-kv 集群 TiKV提供:分布式 kv 存储引擎,提供了 mvcc 功能。可以读取到历史版本数据。
TSO 是利用网卡来对大数据包进行自动分段,降低CPU负载的技术。 GSO 是协议栈分段功能。分段之前判断是否支持TSO,支持则推迟到网卡分段。 如果TSO开启,GSO会自动开启。 UFO 类似TSO,不过只针对UDP报文。 如果TSO开启,GSO会自动开启。 以下是TSO和GSO的组合关系: GSO开启, TSO开启:协议栈推迟分段,并直接传递大数据包到网卡,让网卡自动分段。 GSO开启, TSO关闭:协议栈推迟分段,在最后发送到网卡前才执行分段。 GSO关闭, TSO开启:同GSO开启, TSO开启。 需要注意的是,只要开启了GSO,即使硬件不支持TSO,也会设置NETIF_F_TSO,使得sk_can_gso(sk)在GSO开启或者TSO开启的时候都返回true。
KV/TSO Request OPS 和连接信息在 KV/TSO Request OPS 面板中,你可以查看 KV 和 TSO 每秒请求的数据统计。 TSO 结果。 当 TiDB 完成 parse 和 compile 之后, 进入 execute 阶段,此时存在两个情况:如果 TSO 请求已经完成,Wait 方法会立刻返回一个可用的 TSO 或 error如果 TSO 请求还未完成,Wait 方法会 block 住等待一个可用的 TSO 或 error(说明 gRPC 请求已发送但尚未收到返回结果,网络延迟较高)TSO 等待的时间记录为 TSO WAIT,TSO 请求的网络时间记录为 TSO RPC。
active en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 options=460<TSO4 ,TSO6,CHANNEL_IO> ether 82:17:07:5f:28:00 media: autoselect <full-duplex> status: inactive en2: flags =8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500 options=460<TSO4,TSO6,CHANNEL_IO bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 options=63<RXCSUM,TXCSUM,TSO4 ,TSO6> ether 82:17:07:5f:28:00 Configuration: id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
卸载类型TCP 分段卸载 (TSO) - TCP Segmentation Offload使用 TCP 协议发送大数据包。使用NIC来处理分段,然后将TCP、IP和数据链路层协议头添加到每个分段。 第四个(也是 Linux 中原生支持的最高级别)是 TSO。 通过 TSO,操作系统为硬件提供标头模板,然后为硬件提供大块数据(不超过 64K)以供其分割和校验和,这意味着操作系统需要生成更少的标头,并且设置 DMA 时的任何开销也将大幅减少。 唯一的原因是您的 NIC 上是否有 TOE(TCP 卸载引擎)具有支持 TSO 的硬件的主机将 TCP 数据发送到 NIC,而无需在软件中对数据进行分段。 LRO/TSO 不直接对 ack 机制负责(尽管它确实依赖于 GBN(回退N步-go-back-n))。
On x86 (or other TSO): no. On x86 (or other TSO): yes! On x86 TSO model: yes! On x86 TSO model: no. (Example from x86-TSO paper.) 为了解决这些问题,欧文斯等人提出了 x86-TSO 模型 ,它基于早期的 SPARCv8 TSO 模型,当时它们声称:“据我们所知,x86-TSO 是可靠的,足够强大的,可以进行以上编程,并且大体上符合供应商的意图
7. x86-TSO x86-TSO是Intel推出的一种CPU内存一致性模型,特点是只有“Store Load”一种情况会重排序,也就是“Load”可以排(乱序)在“Store”的前面,因此不需要 内存模型 https://www.cl.cam.ac.uk/~pes20/weakmemory/x86tso-paper.tphols.pdf(A Better x86 Memory Model: x86-TSO) http://homepages.inf.ed.ac.uk/vnagaraj/papers/hpca14.pdf(TSO-CC: Consistency directed cache coherence for TSO) 7) Sequential Consistency &TSO https://www.cis.upenn.edu/~devietti/classes/cis601 -spring2016/sc_tso.pdf 8) Write buffer https://en.wikipedia.org/wiki/Write_buffer 9) x86-64和IA-
language_iso_code %in% c("tso", "hau", "pcm", "swa")) |> mutate(language = if_else( = 1, alpha = 1/2, data = target_map |> filter(language_iso_code %in% c("tso