Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于线程模型 #3

Closed
songzhi opened this issue Jul 16, 2024 · 11 comments
Closed

关于线程模型 #3

songzhi opened this issue Jul 16, 2024 · 11 comments

Comments

@songzhi
Copy link

songzhi commented Jul 16, 2024

我观察到目前的线程模型是 shared-everything,每处理一个请求就要拿全局锁,并且直到请求执行完成才释放。

这样有几个缺点:

  1. 并发请求被迫串行化,这甚至比 Redis 官方实现的还要糟,后者可以在单线程内任意并发。
  2. 如果多个并发请求分别由几个线程进行处理,不同线程访问同一块内存,即使有锁保证正确性,也对 cpu 缓存不友好,会造成cache thrashing。

我的建议:
线程模型改为 shared-nothing,一个 database 的所有访问请求只能在同一个线程被处理,也就是说 Database: !Send。网络连接则可以在线程间任意传递,处理请求时只要通过消息传递转发到对应的 database 就行。不同的 database 可以处于不同的线程,以实现扩展性,后期还可以提供自动 sharding 的中间件。

@sleeprite
Copy link
Owner

sleeprite commented Jul 16, 2024

这也是我最近迫切希望解决的问题,有很多方案也在积极探索中,感谢你的提案。

我理解你的建议是降低锁的粒度,将 db 的实例锁,下放一层,到具体的 db,减少锁资源的竞争。

如果这样的话,对于不同 db 的不同数据结构上锁,似乎可以进一步提高性能,但终究都会有上锁和释放锁的性能损耗。除此之外,rudis 是否可以使用无锁编程等方式,能有更多的提升空间。

另外,我也在考虑 rwlock 是否能代替 m 锁,在读的工作上避免锁的存在,对此你有什么好的建议

@songzhi
Copy link
Author

songzhi commented Jul 17, 2024

不需要锁,网络请求通过消息传递传给某个 database 的 worker,而这个 worker 因为不会跨线程工作,所以 database 内的所有数据结构都可以是线程不安全的。这种线程模型就是 Redis 官方的线程模型,Redis 只在网络请求处理部分做了多线程,核心数据结构还是单线程的。这样做的性能是最好的,只是扩展性不够,这个问题可以通过 sharding 的方式解决。无锁数据结构并不是免费的午餐,理论上性能最好的方式就是避免任何CPU核间通讯。

@sleeprite
Copy link
Owner

sleeprite commented Jul 17, 2024

不需要锁,网络请求通过消息传递传给某个 database 的 worker,而这个 worker 因为不会跨线程工作,所以 database 内的所有数据结构都可以是线程不安全的。这种线程模型就是 Redis 官方的线程模型,Redis 只在网络请求处理部分做了多线程,核心数据结构还是单线程的。这样做的性能是最好的,只是扩展性不够,这个问题可以通过 sharding 的方式解决。无锁数据结构并不是免费的午餐,理论上性能最好的方式就是避免任何CPU核间通讯。

再次感谢你的提案,并给出了耐心的解释,未来几个版本我们将针对代码进行进一步的调整,如果你对此也有兴趣,也欢迎你的加入 >_<

@acking-you
Copy link

这方面可以不要用 tokio,改用 monoio 解决,当然我觉得最大的问题可能不是这个,我觉得可能是代码质量和代码风格以及模块拆分的一点也不 rust,很多可以 zero cost 实现的部分都感觉在写 Java,作为玩具来开发的话感觉挺好,但是如果作为真正想落地生产的项目,太欠火候了(就算再多人参与,这基础的框子没搭好,后续也很难维护)...... 总的来看,可能作者刚写 rust 没多久,丧失很多的性能敏感的 sense

@sleeprite
Copy link
Owner

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。

此外,我近期看下你提到的 monoio,看看能否有些启发

@acking-you
Copy link

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。

此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

@sleeprite
Copy link
Owner

sleeprite commented Jul 20, 2024

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。
此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

我正在 dev 陆续调整 6e3f55c

@sleeprite
Copy link
Owner

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。
此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

dev 已经通过 clippy 编译啦,仅剩一个 warning:Finished dev [unoptimized + debuginfo] target(s) in 0.42s

@acking-you
Copy link

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。
此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

dev 已经通过 clippy 编译啦,仅剩一个 warning:Finished dev [unoptimized + debuginfo] target(s) in 0.42s

一个可持续发展的 rust 项目,应该至少添加一些常见的 clippy 规则来规范代码注释以及规范的编写(虽然一般根据不同项目开启的严格程度不同,见过最严格的会开到整数加法都会检查溢出,但最基本的注释没见过哪个项目是没有开的)

一般这三个是最基本的
#![doc = include_str!("../README.md")]
#![deny(missing_docs, rustdoc::broken_intra_doc_links)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

@sleeprite
Copy link
Owner

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。
此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

dev 已经通过 clippy 编译啦,仅剩一个 warning:Finished dev [unoptimized + debuginfo] target(s) in 0.42s

一个可持续发展的 rust 项目,应该至少添加一些常见的 clippy 规则来规范代码注释以及规范的编写(虽然一般根据不同项目开启的严格程度不同,见过最严格的会开到整数加法都会检查溢出,但最基本的注释没见过哪个项目是没有开的)

一般这三个是最基本的 #![doc = include_str!("../README.md")] #![deny(missing_docs, rustdoc::broken_intra_doc_links)] #![cfg_attr(docsrs, feature(doc_auto_cfg))]

你是否可以帮助我们来构建这套规则体系,如果可以感谢你的帮助

@acking-you
Copy link

很多可以 zero cost 实现的部分都感觉在写 Java

评价的很到位,我是一个 5 年 java,偶尔写写 js,所以在 rust 的编码上有一些其他语言的习惯,但是有用心写,命令的扩展上也有考虑到,可能实现上有一股 java 味,你可以提供一些参考性的建议,帮助我们来改进它。
此外,我近期看下你提到的 monoio,看看能否有些启发

代码风格也应该规范一下,比如 cargo clippy 至少得过吧

dev 已经通过 clippy 编译啦,仅剩一个 warning:Finished dev [unoptimized + debuginfo] target(s) in 0.42s

一个可持续发展的 rust 项目,应该至少添加一些常见的 clippy 规则来规范代码注释以及规范的编写(虽然一般根据不同项目开启的严格程度不同,见过最严格的会开到整数加法都会检查溢出,但最基本的注释没见过哪个项目是没有开的)
一般这三个是最基本的 #![doc = include_str!("../README.md")] #![deny(missing_docs, rustdoc::broken_intra_doc_links)] #![cfg_attr(docsrs, feature(doc_auto_cfg))]

你是否可以帮助我们来构建这套规则体系,如果可以感谢你的帮助

闲暇时间我也想搞搞,但应该很难闲下来😭

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants