算法模块如何保证依赖数据的同步

Posted 穿越临界点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法模块如何保证依赖数据的同步相关的知识,希望对你有一定的参考价值。

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的无效信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。

文章目录

1 问题

一个算法模块运行时可能会遇到某个奇怪的计算错误或误差过大的问题。但查询代码并不会发现有任何逻辑问题。

此时,你可能遇到了依赖的数据不同步的问题。

2 原因

举例说明:假设你的算法计算时依赖全局数据D1和D2,在t1时刻使用了D1数据,在t2时刻使用D2数据时,它却已经被其它线程改变了,造成数据D1和D2不匹配的情况,导致计算出错或者误差过大。

根因就是依赖多个全局数据时,修改全局数据的有多个线程,并且未做线程同步或数据同步。

3 解决方案

针对上述问题,破坏任何一个导致该问题的条件就可以解决改问题,可以根据需要选择。

3.1 线程同步

可以使用线程同步机制,比如加锁。

具体操作方法是,在主线程中计算访问所有的依赖数据(D1-Dn)前先获取一把锁(定义该锁为外层锁,以便与内层锁(D1-Dn每个数据都对应一把锁)区别),使用完之后再释放。保证在计算过程中所依赖的所有数据不被其他线程改变。

缺点是,效率太低,可能会严重影响系统的实时性。假如D1-Dn数据每个数据更新都在独立线程中更新,算上主线程则会有n+1个线程同时争夺一把锁,当n比较小,或者数据更新频率比较低时,可以使用该方法。

3.2 拷贝副本

拷贝副本就好比是给当前时刻的所有数据(D1-Dn)拍一个快照,后续主线程的计算就依赖该快照进行计算。

3.1 使用局部变量副本

一种拷贝副本的方法就是使用函数入参方式拷贝副本。类似函数式编程。

该方法适合依赖数据和计算流程比较简单的情况。因为函数式编程确实挺不灵活的。

3.2 使用全局变量副本

这种方法就是直接拷贝一份依赖数据到另一个全局变量,该全局变量只能主线程自己访问。

由于拷贝的时间很短(有特殊情况可以酌情处理)可以不用加外层锁(如果真的需要加锁,使用函数传参的方式同样需要加锁),因为拷贝的这个时间段内可以认为依赖的数据时间戳是对齐的。

但内层锁还是需要加的(需要覆写operator =,里面获取内层锁)。因为加内层锁不会严重影响系统效率,加外层锁会。

4 总结

  1. 遇到非逻辑问题,考虑是否是系统问题。
  2. 算法模块需要保证依赖的数据时间戳的同步。
  3. 可以根据具体情况选择线程同步或者拷贝副本的方案。

恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~

以上是关于算法模块如何保证依赖数据的同步的主要内容,如果未能解决你的问题,请参考以下文章

算法模块如何保证依赖数据的同步

Zookeeper 如何保证分布式系统数据一致性

缓存同步如何保证缓存一致性缓存误用!

缓存同步如何保证缓存一致性缓存误用

讨论:缓存同步如何保证缓存一致性缓存误用

面试官:如何保证用户模块的数据安全?说说你的解决方案