实现数据缓存一致性都有哪些方法
数据一致性问题是我们在学习软件编程开发技术的时候需要重点掌握的一个编程知识,而今天我们就通过案例分析来了解一下,实现数据缓存一致性都有哪些方法。
CPU在读写数据的时候,都是在CPUCache读写数据的,原因是Cache离CPU很近,读写性能相比内存高出很多。对于Cache里没有缓存CPU所需要读取的数据的这种情况,CPU则会从内存读取数据,并将数据缓存到Cache里面,后CPU再从Cache读取数据。
而对于数据的写入,CPU都会先写入到Cache里面,然后再在找个合适的时机写入到内存,那就有「写直达」和「写回」这两种策略来保证Cache与内存的数据一致性:
写直达,只要有数据写入,都会直接把数据写入到内存里面,这种方式简单直观,但是性能就会受限于内存的访问速度;
写回,对于已经缓存在Cache的数据的写入,只需要更新其数据就可以,不用写入到内存,只有在需要把缓存里面的脏数据交换出去的时候,才把数据同步到内存里,这种方式在缓存命中率高的情况,性能会更好;
当今CPU都是多核的,每个核心都有各自独立的L1/L2Cache,只有L3Cache是多个核心之间共享的。所以,我们要确保多核缓存是一致性的,否则会出现错误的结果。
要想实现缓存一致性,关键是要满足2点:
一点是写传播,也就是当某个CPU核心发生写入操作时,需要把该事件广播通知给其他核心;
二点是事物的串行化,这个很重要,只有保证了这个,次啊能保障我们的数据是真正一致的,我们的程序在各个不同的核心上运行的结果也是一致的;
基于总线嗅探机制的MESI协议,就满足上面了这两点,因此它是保障缓存一致性的协议。
MESI协议,是已修改、独占、共享、已实现这四个状态的英文缩写的组合。整个MSI状态的变更,则是根据来自本地CPU核心的请求,或者来自其他CPU核心通过总线传输过来的请求,从而构成一个流动的状态机。另外,对于在「已修改」或者「独占」状态的CacheLine,修改更新其数据不需要发送广播给其他CPU核心。