• 目录:

    关于机械硬盘


    引言

    固态硬盘已经出现n年了, 大概还是价格的原因, 工程师们依旧与机械硬盘奋战着. 举几个例子, 感受下 if else 之外的代码乐趣.

    QMQ 中针对硬盘IO的优化

    qmq 是去哪儿网自研的消息队列. 相比于 RabbitMQ, Kafka 等消息中间件, qmq 在复杂业务场景的适用性上拥有绝对的优势. 延迟消息, 广播消息, tag过滤, 轨迹跟踪, 事物消息, Consumer扩容 这些在使用其他消息队列时让人叫苦连天的特性, 对qmq来说都不是事儿.

    在消息的接收端, qmq采用了分层的存储模型.

    第一层用固态硬盘, 主要负责写消息. 只要消息成功写入固态硬盘, 就可以向客户端返回消息发送成功.

    固态硬盘中的消息接下来会被转写到第二层机械硬盘, 这样在享受了固态硬盘的写入速度的同时, 又降低了对固态硬盘容量的要求. 只需要小容量低成本的固态硬盘, 就可以实现消息接收性能的大幅度提升.

    第二层机械硬盘, 主要用来读取消息. 在存储上也有相应优化: 先是不同topic的消息, 写入到了同一个log中, 再是在消息转写到机械硬盘的过程中, 还对消息进行了排序, 相同topic的消息尽量排到一起.

    不同topic的消息, 写入到了同一个log中, 相对较容易理解: 假设n个消费者在拉取不同topic的消息, 如果是一个topic对应一个log文件, 硬盘磁头必然在不同log文件之间来回切换. 在消息没有积压的情况下, 单个log文件就完全避免了这种情况.

    如果个别topic消息积压, 磁头依然会在单个log文件的前后来回移动. 这就要分两种情况, 如果积压的消息消费很快, 那相同topic的消息排到一起, 对减少随机读取就有一定的帮助作用.

    如果积压的消息消费速度也慢呢? qmq采取的是动态限速的策略, 统计消费者的消费速度, 降低消费慢的消费者的优先级.

    MYSQL 数据多了查询就会慢吗?

    有过这样的压测经历, 压测前需要造数据量, 在mysql单表中插入了几千万条数据, 但是这些数据都是跑不通接口跑不通业务流程的脏假数据. 然后手动生成了一份可用的数据, 压测时就用这一份能跑通流程的数据作参数来压.

    这样的得到的结果真的符合线上的场景吗? 我们来从理论上分析一下.

    场景再定得详细一点, 一个查询单个用户信息的接口, select * from user where id=?, 如果压测时用户id固定不变, 不考虑各处缓存在这中间的作用, 硬盘磁头也只需要待在一个地方不动. 但是线上的场景, 往往是大量不同的用户来获取自己的信息. 磁头需要来回移动.

    也不能直接否定这种压测造数的方式, 假设是针对课程或考试的压测, 前提条件, 我们可以认为只会有个别热点课程 或者 个别客户组织了一场大型考试, 课程id和考试id可以只固定几个.

    所以, 结论是, 直接从业务场景上模拟得更真实点, 可以完全绕开这个坑. 只查一条数据, id固定的情况下, 不会慢.

    感觉白分析了这么久, 没啥实用价值.

    为什么数据库更应该独享磁盘

    即使是上面讲到的特例, 只查一条数据, id固定. 原本不需要移动磁头. 这时候硬盘被其他程序共享, 磁头移动到其他地方读了个文件..哦吼…