左耳听风 -- 技术基础
技术变现
技术领导力
Go + Docker
学习 + 职业
Leader
时间管理
故障处理
表象 + 本质
参考资料左耳听风
计算机组成 -- Disruptor
缓存行填充缓存行大小1234567$ sysctl -a | grep -E 'cacheline|cachesize'hw.cachesize: 17179869184 32768 262144 6291456 0 0 0 0 0 0hw.cachelinesize: 64hw.l1icachesize: 32768hw.l1dcachesize: 32768hw.l2cachesize: 262144hw.l3cachesize: 6291456
RingBufferPad1234abstract class RingBufferPad{ protected long p1, p2, p3, p4, p5, p6, p7;}
变量p1~p7本身没有实际意义,只能用于缓存行填充,为了尽可能地用上CPU Cache
访问CPU里的L1 Cache或者L2 Cache,访问延时是内存的1/15乃至1/100(内存的访问速度,是远远慢于CPU Cache的)
因此,为了追求极限性能,需要尽可能地从CPU Cache里面读取数据
CPU ...
计算机组成 -- DMP
DMP系统
DMP(Data Management Platform,数据管理平台)
DMP系统广泛应用在互联网的广告定向,个性化推荐
DMP系统会通过处理海量的互联网访问数据以及机器学习算法,给用户标注上各种各样的标签
然后在做个性化推荐和广告投放的时候,再利用这些标签,去做实际的广告排序、推荐等工作
对于外部使用DMP的系统或者用户来说,可以简单地把DMP看成一个Key-Value数据库
对Key-Value系统的预期,以广告系统为案例
低响应时间
一般的广告系统留给整个广告投放决策的时间大概是10ms
因此对于访问DMP系统获取用户数据,预期的响应时间都在1ms以内
高可用性
DMP系统常用于广告系统,如果DMP系统出问题,意味着在不可用的时间内,整个广告收入是没有的
因此,对于可用性的追求是没有上限的
高并发
如果每天要响应100亿次广告请求,QPS大概是12K
海量数据
如果有10亿个Key,每个用户有500个标签,标签有对应的分数
标签和分数都用4 Bytes的整数来表示,总共大概需要4TB的数据
低成本
广告系统的收入通常用CPM(Cost Per Mille,千次曝光成本) ...
计算机组成 -- DMA
背景
无论IO速度如何提升,比起CPU,还是太慢,SSD的IOPS可以达到2W,但CPU的主频有2GHz
对于IO操作,都是由CPU发出对应的指令,然后等待IO设备完成操作后返回,CPU有大量的时间都是在等待IO设备完成操作
在很多时候,CPU的等待是没有太多的实际意义的
对于IO设备的大量操作,其实都只是把内存里面的数据,传输到IO设备而已,此时CPU只是在傻等
当传输的数据量比较大的时候,如大文件复制,如果所有数据都要经过CPU,实在有点太浪费时间
因此发明了DMA技术,即直接内存访问(Direct Memory Access),来减少CPU等待的时间
协处理器
本质上,DMA技术就是在主板上一块独立的芯片
在进行内存和IO设备的数据传输的时候,不再通过CPU来传输数据
而直接通过DMA控制器(DMA Controller,DMAC),其实是一个协处理器(Co-Processor)
DMAC最有价值的地方:当要传输的数据特别大,速度特别快,或者传输的数据特别小、速度特别慢的时候
用千兆网卡或者硬盘传输大量数据的时候,如果都用CPU来搬运的话,肯定忙不过来,可以选择DMAC
当数据传输很慢 ...
计算机组成 -- SSD
对比
访问类型
机械硬盘(HDD)
固态硬盘(SSD)
随机读
慢
非常快
随机写
慢
快
顺序写
快
非常快
耐用性(重复擦写)
非常好
差
读写原理
CPU Cache用的SRAM是用一个电容来存放一个比特的数据
对于SSD硬盘,由一个电容加上一个电压计组合在一起,就可以记录一个或多个比特
分类
SLC:Single-Level Cell
MLC:Multi-Level Cell
TLC:Triple-Level Cell
QLC:Quad-Level Cell
QLC
想要表示15个不同的电压,充电和读取的时候,对精度的要求就会更高,这会导致充电和读取的时候更慢
QLC的SSD的读写速度要比SLC慢上好几倍
PE擦写问题
控制电路
常用的是SATA或者PCI Express接口,里面有一个很重要的模块:FTL(Flash-Translation Layer),即内存转换层
FTL是SSD的核心模块,SSD性能的好坏很大程度上取决于FTL的算法好不好
实际的IO设备
新的大容量SSD都是3D封装的,即由很多裸片(Die)叠在一起(跟HDD有点类似)
一个 ...
计算机组成 -- HDD
物理构造一块机械硬盘由盘面、磁头、悬臂三个部件组成
盘面
盘面(Disk Platter)是我们实际存储数据的盘片
盘面本身通常是用铝、玻璃或者陶瓷这样的材质去做成光滑盘片,然后在盘面上有一层磁性的涂层,数据就存储在磁性的涂层上
盘面中间有一个受电机控制的转轴(控制盘面去旋转),转速:RPM(Rotations Per Minute)
磁头
通过磁头(Drive Head),从盘面上读取数据,然后再通过电路信号传输给控制电路和接口,再到总线上
通常,一个盘面上会有两个磁头,分别是盘面的正反面,盘面在正反面都有对应的磁性涂层来存储数据
一块硬盘不会只有一个盘面,而且上下堆叠了很多个盘面,各个盘面之间是平行的,每个盘面的正反两面都有对应的磁头
悬臂
悬臂(Actutor Arm)链接在磁头上,并且在一定范围内去把磁头定位到盘面的某个特定磁道(Track)上
一个盘面通常是圆形的,由很多同心圆组成,每个同心圆都是一个磁道,每个磁道都有编号
随机读写
一个磁道,会分成多个扇区(Sector),上下平行的盘面的相同扇区,组成一个柱面(Cylinder)
数据读取的步骤
把盘面旋转到某个位置,在这个位置,悬 ...
计算机组成 -- IO_WAIT
IO性能
硬盘厂商的性能报告:响应时间(Response Time)、数据传输率(Data Transfer Rate)
HDD硬盘一般用的是SATA 3.0的接口;SSD硬盘通常会用两种接口,一部分用SATA 3.0接口,另一部分用PCI Express接口
数据传输率
SATA 3.0接口的带宽是6Gb/s ≈ 768MB/s
日常用的HDD硬盘的数据传输率,一般在200MB/s
SATA 3.0接口的SSD的数据传输率差不多是500MB/s
PCI Express接口的SSD,读取时的数据传输率能到2GB/s,写入时的数据传输率也能有1.2GB/s,大致是HDD的10倍
响应时间
程序发起一个硬盘的读取或写入请求,直到请求返回的时间
SSD的响应时间大致在几十微秒这个级别,HDD的响应时间大致在十几毫秒这个级别,相差几十倍到几百倍
IOPS
每秒读写的次数,相对于响应时间,更关注IOPS这个性能指标
在顺序读写和随机读写的情况下,硬盘的性能是完全不同的
IOPS和DTR才是IO性能的核心指标
在实际的应用开发当中,对于数据的访问 ...
计算机组成 -- IO设备
接口 + 设备 – 适配器模式
大部分的输入输出设备,都有两个组成部分,一个是接口,另一个是实际的IO设备
硬件设备并不是直接接入到总线上和CPU通信的,而是通过接口,用接口连接到总线上,再通过总线和CPU通信
串行接口、USB接口等都是计算机主板上内置的各个接口,实际使用的硬件设备,都需要插入到这些接口上,才能和CPU通信
接口本身是一块电路板,CPU不需要和实际的硬件设备打交道,只需要和这个接口电路板打交道
设备里面的三类寄存器(状态寄存器、命令寄存器、数据寄存器),都在接口电路上,而不在实际的设备上
除了内置在主板上的接口外,有些接口可以集成在设备上 – IDE(Integrated Device Electronics)硬盘
设备的接口电路直接在设备上,只需要通过一个线缆,把集成了接口的设备连接到主板上即可
接口和设备分离:各种输入输出设备的制造商,根据接口的控制协议,来设计各种外设
Windows设备管理器
Devices:着重实际的IO设备本身
Controllers:着重输入输出设备接口里面的控制电路
Adaptors:着重接口作为一个适配器后面可以插上不同的实际设备
CPU控 ...
计算机组成 -- 总线
设计来源:降低复杂度
计算机内部有很多不同的硬件设备,除了CPU和内存,还有大量的输入输出设备
如果各个设备间的通信,都是互相之间单独进行的,如果有N个不同的设备,他们之间需要各自单独连接,那么系统复杂度为**$N^2$**
为了简化系统的复杂度,引入了总线,把**$N^2$复杂度,变成了$N$**的复杂度
CPU想要和什么设备通信,通信的指令是什么,对应的数据是什么,都发送到这个线路上
设备想要向CPU发送什么消息,也发送到这条线路上
这条线路好像一个高速公路,各个设备和其他设备之间,不需要单独建公路,只需要建一条小路通向这条高速公路即可
总线(Bus),其实就是一组线路,CPU、内存、输入输出设备,都是通过这组线路,进行相互间通信的
设计模式:事件总线
在大型系统开发的过程中,经常会用到一种叫作事件总线(Event Bus)的设计模式
系统中的各个组件之间需要相互通信,如果两两之间单独去定义协议,复杂度为**$N^2$**
各个模块触发对应的事件,并把事件对象发送到总线上,即每个模块都是一个发布者(Publisher)
各个模块也会把自己注册到总线上,去监听总线上的事件
并根据事件的对象类型 ...
计算机组成 -- 内存
程序装载
在Linux或Windows下,程序并不能直接访问物理内存
内存需要被分成固定大小的页,然后通过虚拟内存地址到物理内存地址的地址转换,才能到达实际存放数据的物理内存位置
程序看到的内存地址,都是虚拟内存地址
地址转换简单页表
页表(Page Table,一一映射):<**虚拟**内存的页, **物理**内存的页>
页表:把一个内存地址分成页号(Directory)和偏移量(Offset)两部分
前面的高位,是内存地址的页号;后面的低位,是内存地址的偏移量
页表只需要保留虚拟内存地址的页号和物理内存地址的页号之间的映射关系即可
同一个页里面的内存,在物理层面是连续的
对于32位的内存地址,4KB大小的页,需要保留20位的高位,12位的低位
内存地址转换步骤
把虚拟内存地址,切分成页号和偏移量
从页表里面,查询出虚拟页号对应的物理页号
直接拿到物理页号,加上前面的偏移量,得到物理内存地址
空间问题
32位的内存地址空间,页表一共需要记录2^20个到物理页号的映射关系
一个页号是完整的32位的4 Bytes,一个页表就需要4MB的空间(2^20 * 4 Bytes ...