记忆的回声 | 青训营笔记

75 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天,储存系统是我们接触良久的概念,今天进一步的了解了它,有了一些感悟,回答了一些思考题,希望能对别人有所帮助。

写入存储系统的粒度太大,会不会导致数据原子性问题?例如一次性写100MB,如果系统突然crash,会不会只有一部分数据持久化了,另一部分丢失了?如果要解决原子性问题,一般会设计什么机制:

是的,写入存储系统的粒度太大可能会导致数据原子性问题。在你的例子中,如果一次性写入100MB数据,并且系统在写入过程中crash,可能会导致只有一部分数据持久化了,另一部分数据丢失。

要解决原子性问题,可以使用事务来保证操作的原子性。一个事务是一组原子性操作的集合,这些操作要么全部完成,要么全部失败。如果一个事务中的任何一步失败,整个事务都会回滚到初始状态,因此不会有一部分数据被持久化,另一部分数据丢失的情况。

在设计系统时,可以使用如下几个机制来确保操作的原子性:

1.事务:像关系型数据库中就提供了事务的支持,通过事务,可以保证一组操作的原子性,如果事务中任何一步失败,整个事务都会回滚到初始状态。

2.写前日志(Write-ahead logging,WAL):在执行写入操作之前,先将所有操作写入日志文件中,这样即使在写入过程中crash,也可以通过日志恢复到上一次正常状态。

3.多版本并发控制(Multiversion Concurrency Control,MVCC):在写入新数据时,不覆盖原有数据,而是在存储系统中保留多个版本,通过版本号来区分不同版本的数据,从而实现原子性。

4.分布式锁(Distributed lock):通过分布式锁来控制对数据的访问,确保同一时刻只有一个线程可以对数据进行修改,从而保证操作的原子性。

这些机制可以单独使用,也可以组合使用,以满足不同应用场景的需求。

 

 

 

一个关系型数据库大概率是会被并发访问的,如果要保证并发安全,除了在行数据上加悲观锁还有其他方式吗?

除了在行数据上加悲观锁以外,还有其他一些方式可以保证关系型数据库的并发安全,例如:

  • 乐观锁:在读取数据时,记录一个版本号或时间戳,当修改数据时,检查当前版本是否与读取时的版本一致,如果一致则更新数据并增加版本号,否则返回错误。

  • MVCC(多版本并发控制):每个事务都有自己的时间戳,当读取数据时,只读取该事务创建时间之前的数据版本。这种方式可以避免读取数据时被其他事务修改的问题。

  • 数据库分区(sharding):将数据按照某个维度进行分区,不同分区的数据存储在不同的物理节点上,从而降低不同节点之间的并发访问冲突。

  • 内存数据库:将数据存储在内存中,可以避免磁盘I/O的性能瓶颈,提高并发访问能力。

  • 数据库连接池:通过复用数据库连接,可以减少连接建立和关闭的开销,从而提高并发访问能力。

以上这些技术可以与悲观锁结合使用,从而实现更可靠的并发控制。但需要注意,不同的并发控制技术适用于不同的场景,需要根据实际需求选择合适的技术方案。