《了解了实现再谈网络性能》

0. intro 《理解了实现再谈网络性能》,作者张彦飞,github 1. 内核是如何接收网络包的 在Linux内核实现中,链路层协议靠网卡驱动来实现,网络层、传输层由内核协议栈来完成。 内核收包的路径示意图: 注意:当RingBuffer满的时候,新来的数据包将给丢弃。ifconfig查看⽹卡的时候,可以 ⾥⾯有个overruns,表示因为环形队列满被丢弃的包。如果发现有丢包,可能需要通过ethtool命令来加⼤环形队列的⻓度 ⾸先在开始收包之前,Linux 要做许多的准备⼯作: 创建ksoftirqd线程,为它设置好它⾃⼰的线程函数(后⾯使用它来处理软中断) 协议栈注册,linux要实现许多协议,⽐如arp,icmp,ip,udp,tcp,每⼀个协议都会将⾃⼰的处理函数注册⼀下,⽅便包来了迅速找到对应的处理函数 ⽹卡驱动初始化,每个驱动都有⼀个初始化函数,内核会让驱动也初始化⼀下。在这个初始化过程中,把⾃⼰的DMA准备好,把NAPI的poll函数地址告诉内核 启动⽹卡,分配RX,TX队列,注册中断对应的处理函数 以上是内核准备收包之前的重要⼯作,等这些步骤都 ready 之后,打开硬中断,等待数据包的到来: ⽹卡将数据帧 DMA 到内存的 RingBuffer 中,然后向 CPU 发起中断通知 CPU 响应中断请求,调⽤⽹卡启动时注册的中断处理函数。中断处理函数完成后,发起软中断请求 内核线程 ksoftirqd 线程发现有软中断请求到来,先关闭硬中断。 ksoftirqd 线程开始调⽤驱动的 poll 函数收包 poll 函数将收到的包送到协议栈注册的 ip_rcv 函数中 ip_rcv 函数再将包送到 udp_rcv 函数中(对于 tcp 包就送到 tcp_rcv ) 2. 内核是如何与进程进行协作的 sock_owned_by_user 判断的是⽤户是不是正在这个 socket 上进⾏系统调⽤( socket 被占⽤),如果没有,那就可以直接放到 socket 的接收队列中。如果有,那就通过 sk_add_backlog 把数据包添加到 backlog 队列。 当⽤户释放的 socket 的时候,内核会检查 backlog 队列,如果有数据再移动到接收队列中。 sk_rcvqueues_full 接收队列如果满了的话,将直接把包丢弃。- 接收队列⼤⼩受内核参数 net....

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《了解了实现再谈网络性能》目录

intro 目录索引 理解了实现再谈网络性能

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第01章-MySQL架构与历史

1.1 MySQL 逻辑架构 1.1.1 1.1.2 优化与执行 MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序、选择合适的索引等。 用户可以通过特殊的关键字提示(hint)优化器,影响它的决策过程。 可以请求优化器解释(explain)优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema、修改相关配置。 对于select语句,在解析查询之前,服务器会先检查查询缓存(Query Cache),如果能找到对应查询,服务器就不必再执行查询解析、优化和执行整个过程。 1.2 并发控制 MySQL在两个层面的并发控制:服务器层与存储引擎层 1.2.1 读写锁 1.2.2 锁粒度 读写锁 锁粒度 1.3 事务 A(atomicity)C(consistency)I(isolation)D(durability) 1.3.1 隔离级别 READ UNCOMMITTED (未提交读) READ COMMITTED (读提交) REPEATABLE READ (可重复读) SERIALIZABLE (可串行化) 1.3.2 死锁 数据库实现了各种死锁检测和死锁超时机制 InnoDB目前处理死锁的方法是:将持有最少行级排他锁的事务进行回滚。 死锁发生后,只有部分或完全回滚其中一个事务,才能打破死锁。对于事务型的系统,这是无法避免的,所有应用程序在设计时必须考虑如何处理死锁。 1.3.3 事务日志 事务日志可以帮助提高事务的效率,不必每次都将修改的数据本身持久化到磁盘。 事务日志采用的是追加的方式,写日志操作是磁盘上一小块区域的顺序I/O,比每次修改都写回数据库对应磁盘位置可能导致的随机I/O要快 事务日志持久化后,可以慢慢地刷回磁盘。 以上这种设计,被称为预写式日志 (Write-Ahead Logging) 隐式和显式锁定 InnoDb采用的是两段锁协议(two-phase locking protocol) 事务执行的过程中,随时都可以锁定,但是只有在commit和rollback时同时释放。 InnoDB支持显示锁定:(非标准SQL) 1 2 select....

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第02章-MySQL基准测试

2.1 为什么需要基准测试 2.2 基准测试的策略 2.2.1 测试何种指标 吞吐量:单位时间内的事务处理数 (每秒事务数TPS) 响应时间或延迟:通常使用百分比响应时间来代替最大响应时间 并发性: 可扩展性: 2.3 基准测试方法 错误的基准测试方法: 使用真实数据的子集而不是全集 使用错误的数据分布 使用不真实的分布参数 在多用户场景中,只做单用户测试 在单服务器上测试分布式应用 与真实用户行为不匹配 反复执行同一个查询 没有检查错误 忽略了系统预热(warm up)的过程 使用默认的服务器配置 测试时间太短 2.3.2 基准测试应该运行多长时间 一个常见的错误的测试方式是,只执行一系列短期的测试,比如60秒。 2.3.3 获取系统性能和状态 2.3.4 获取准确的测试结果 2.3.5 运行基准测试并分析结果 2.4 基准测试工具 2.4.1 集成式测试工具 2.4.2 单组件式测试工具 2.5 基准测试案例 2.5.3 sysbench: oltp、fileio

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第03章-服务器性能剖析

3.1 3.1.1 通过性能剖析进行优化 - 两种性能剖析:基于执行时间的分析和基于等待的分析 3.1.2 理解性能剖析 - 值得优化的查询 - 异常情况 - 未知的未知: - 被隐藏的细节 3.2 对应用程序进行性能剖析 3.3 剖析MySQL查询 3.3.1 剖析服务器负载 慢查询日志 分析查询日志 以一些典型的时间窗口如业务高峰期的一个小时内记录查询 pt-query-digest 分析MySQL查询日志的工具 3.3.2 剖析单条查询 show profile 查看时间消耗 直接查询information_schema中对应的表,可以排序 使用show status:返回一些计数器,其中有全局级的、会话级的 使用慢查询日志 使用performance schema 3.3.3 使用性能剖析 3.4 诊断间歇性问题 3.4.1 单条查询问题还是服务器问题 较高频率的执行show global status ,如1秒一次 show processlist,观察是否有大量线程处于不正常的状态或者其他不正常的特征。 使用查询日志 3.4.2 捕获诊断数据 3.4.3 一个诊断案例 3....

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第04章-Schema与数据类型优化

4.1 选择优化的数据类型 更小的通常更好: 应该尽量的使用可以正确存储数据的最小数据类型。更小的数据类型通常更快,占用更少的磁盘、内存、CPU缓存,处理时需要的CPU周期更少 简单就好:简单数据类型的操作通常需要更少的CPU周期。例如整型比字符操作代价更低 尽量避免NULL: 通常情况下最好指定列为NOT NULL。因为如果查询中包含可谓NULL的列,对MySQL来说更难优化优化,NULL使得索引、索引统计和值比较都更复杂 将NULL改为NOT NULL带来的性能提升较小 4.1.1 整数类型 TINYINT:8 bit SMALLINT:16 bit MEDIUMINT:24 bit INT:32 bit BIGINT:64 bit 以上全部都支持unsigned MySQL可以为整数类型指定宽度,例如INT(11),但对存储和计算来说,INT(1)和INT(20)是相同的。这么做只是规定了一些交互工具(例如MySQL命令行客户端)用来显示字符的个数 4.1.2 实数类型 float(4 Byte)和double(8 Byte)类型支持使用标准的浮点运算进行近似计算 decimal类型用于存储精确的小数 浮点和decimal类型都可以指定精度 4.1.3 字符串类型 字符串长度定义不是字节数,而是字符数 varchar: 用于存储可变长字符串,它比定长类型更节省空间,因为它仅使用必要空间。(一种情况例外:表使用ROW_FORMAT=FIXED创建,每一行都会使用定长存储) 使用1个或2个字节记录字符串长度。例如,varchar(10)需要11 byte, varchar(1000) 需要1002 byte 以下情况使用varchar是合适的:字符串列的最大长度比平均长度要大很多,列的更新很少,所以碎片不是问题。 InnoDB可以把过长的varchar存储为blob类型 char char类型是定长的,MySQL会删除所有的末尾空格,char适合存储很短的字符串,或者所有值都接近同一个长度。 对于经常变更的数据,char也比varchar要好,因为定长的cahr类型不容易产生碎片。 对于非常短的列,char相比与varchar,没有记录长度的1 byte开销,效率更高。 BLOB和TEXT类型 BLOB和TEXT都是为了存储大数据而设计的字符串数据类型,分别采用二进制和字符方式存储 BLOB存储的是二进制数据,没有排序规则或字符集 TEXT有字符集和排序规则 因为Memory引擎不支持BLOB和TEXT类型,如果查询使用了这两种类型,并且需要使用隐式临时表,将不得不使用MyISAM磁盘临时表(新版本还是?)。解决方法是,使用substring()转换为字符串 TEXT: TINYTEXT SMALLTEXT (TEXT的同义词) TEXT MEDIUMTEXT LONGTEXT BLOB:...

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第05章-创建高性能索引

intro 索引优化通常是优化查询性能的最有效手段 5.1 索引的基础 5.1.1 索引的类型 B-Tree 索引 “B-Tree”这么叫的原因是MySQL在CREATE TABLE和其他语句中也使用该关键字 存储引擎以不同的方式使用B-Tree,例如MyISAM使用前缀压缩技术使得索引更小,但InnoDB则按照原数据格式进行存储;MyISAM索引通过数据的物理位置引用索引的行,而InnoDB则根据主键引用被索引的行 B-Tree 对索引是顺序组织的,很适合查找范围数据。 索引对多个值进行排序的依据是CREATE TABLE语句中定义索引时列的顺序。 索引中的列的顺序十分重要 索引生效的场景: 全值匹配(使用索引中所有列进行匹配) 匹配最左前缀(只使用索引的前几列) 匹配列前缀(每列支持前缀匹配) 匹配范围值 精确匹配某一列并范围匹配另外一列 只访问索引的查询 B-Tree索引的限制: 如果不是按照索引的最左列开始查询,无法使用索引 不能跳过索引中的列 如果查询中某个列的范围查询,则其右边所有的列都无法使用索引优化查找 哈希索引 只有精确匹配索引所有列的查询才有效 Memory引擎显式支持哈希索引 哈希索引只包含索引值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。 不支持排序 不支持部分索引列匹配查找,只支持等值比较查询 如果哈希冲突很多,一些索引的维护操作的代价也会很高,查找也会变慢 空间数据索引(R-Tree) 全文索引 其他索引类型 5.2 索引的优点 索引大大减少了服务器需要扫描的数据量 索引可以帮助服务器避免排序和临时表 索引可以将随机I/O变为顺序I/O 5.3 高性能索引策略 5.3.1 独立的列:索引列不能是表达式的一部分 5.3.2 前缀索引和索引选择性:决定合适的前缀长度 5.3.3 多列索引 5.3.4 选择合适的索引列顺序 通常将选择性最高的列放在前面 同时可能需要根据那些运行频率最高的查询来调整索引列的顺序 总之,让整体执行的次数最少 5.3.5 聚簇索引 优点: 可以把相关数据保存在一起 数据访问更快 使用覆盖索引扫描的查询可以直接使用页节点中的主键值 缺点:...

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀

《高性能MySQL》第06章-查询性能优化

第06章-查询性能优化 设计合理的查询 6.1 查询为什么会慢? 6.2 慢查询基础:优化数据访问 6.2.1 是否数据库请求了不需要的数据 查询了不需要的记录 多表关联时返回全部列 总是取出全部列 重复查询相同的数据 6.2.2 是否在扫描额外的记录 衡量指标: 响应时间 扫描的行数、访问类型 返回的行数 如果发现查询需要扫描大量的数据但是只返回少数的行,那么常见的优化技巧: 使用覆盖索引(无需回表) 改变库表结构。例如使用单独的汇总表 重写这个复杂的查询 6.3 重构查询的方式 6.3.1 一个复杂查询还是多个简单查询 6.3.2 切分查询 6.3.3 分解关联查询 (1)让缓存的效率更高 (2)减少锁的竞争 (3)查询效率可能提升 (4)可以减少冗余记录的查询 (5)在应用层做关联,更容易对数据库进行拆分,更容易做到高性能和可扩展 (6)相当于在应用层做了哈希关联 6.4 查询执行的基础 6.4.1 MySQL 客户端 / 服务器通信协议 MySQL客户端与服务器之间的通信协议是“半双工”的(?) 缺点:无法进行流量控制 max_allowed_packet 查询状态: show full processlist; Sleep Query Locked Analyzing and statistics Copying to tmp table [on disk] Sorting Result Sending Data 6....

created: 2023-04-04  |  updated: 2023-04-04  |  阿秀