分布式事务和队列、ruby、erlang、scala
我有一个涉及多台机器、消息队列和事务的问题。例如,用户点击网页,该点击会向另一台机器发送一条消息,该机器将付款添加到用户的帐户中。每秒可能有数千次点击。事务的各个方面都应该是容错的。
我以前从未处理过这样的事情,但阅读了一下表明这是一个众所周知的问题。
那么我的问题。我是否正确地假设执行此操作的安全方法是使用两阶段提交,但协议是阻塞的,因此我无法获得所需的性能?我通常编写 Ruby,但看起来像 Redis 这样的数据库和 Rescue、RabbitMQ 等消息队列系统并没有真正帮助我很多 - 即使我实现某种两阶段提交,如果 Redis 崩溃,数据也会丢失,因为它本质上只是内存。
所有这些让我开始关注 erlang 和 scala - 但在我涉足并开始学习一门新语言之前,我真的很想更好地理解这是否值得付出努力。具体来说,我是否正确地认为,由于它们的并行处理能力,这些语言是实现像两阶段提交这样的阻塞协议的更好选择,还是我感到困惑?如果是,是否有任何理由选择一个而不是另一个(特别是在这种情况下 - 我知道有很多线程和博客更普遍地比较两者)
对于交叉发布的歉意 - 这是首先发布到堆栈交换但是我已经添加到问题中,这个版本可能更适合这里
I have a problem that involves several machines, message queues, and transactions. So for example a user clicks on a web page, the click sends a message to another machine which adds a payment to the user's account. There may be many thousands of clicks per second. All aspects of the transaction should be fault tolerant.
I've never had to deal with anything like this before, but a bit of reading suggests this is a well known problem.
So to my questions. Am I correct in assuming that a secure way of doing this is with a two phase commit, but the protocol is blocking and so I won't get the required performance? I usually write Ruby, but it appears that DBs like redis and message queuing system like Rescue, RabbitMQ etc don't really help me a lot - even if I implement some sort of two phase commit, the data will be lost if redis crashes because it is essentially memory-only.
All of this has led me to look at erlang and scala - but before I wade in and start learning a new language, I would really like to understand better if this is worth the effort. Specifically, am I right in thinking that because of their parallel processing capabilities, these languages are a better choice for implementing a blocking protocol like two phase commit, or am I confused? And if yes, is there any reason to pick one rather than the other (specifically in this context - i know there are plenty of threads and blogs comparing the two more generally)
Apologies for cross posting - this was first posted to stack-exchange but I've added to the question and this version is probably a better fit here
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1) 两阶段提交不具有容错能力 - 请参阅链接。您要么需要全序广播,要么需要非阻塞原子提交,具体取决于您问题的具体表述。重新解决。
2) 我不会说 Scala 比大多数其他通用语言更适合实现两阶段提交。具体来说,STM、并行 和 分布式集合在这里对您没有帮助。 Scala 参与者和远程参与者可以为你提供一个很好的 API 来发送消息异步(在同一台机器上或远程),但默认情况下它们不会为您提供抽象,例如不同的故障检测器,这对于实现全序广播很有用,例如 - 您仍然需要自己实现这些(另一方面手,我相信Akka 有这些抽象)。
3) 我不能代表 Erlang 和 Ruby,但就 Scala 和 Java 而言,您可能需要考虑看看 Akka。它基于分布式参与者模型,还支持事务和不同级别的容错能力。重用他们的基础设施可能比从头开始编写自己的分布式容错运行时更好。
1) 2 phase commit is not fault tolerant - see the link. You either need a total order broadcast, or a non-blocking atomic commit, depending on the exact formulation of the problem you're solving.
2) I wouldn't say that Scala is much more suited than most other general purpose languages for implementing a two-phase commit. Specifically, STMs, parallel and distributed collections will not help you here. Scala actors and remote actors may provide you with a nice API to send messages around asynchronously (on the same machine or remotely), but they do not by default give you abstractions such as different failure detectors which would be useful for implementing total order broadcasts, for example - you'll still have to implement these yourself (on the other hand, I believe Akka has these abstractions).
3) I cannot speak for Erlang and Ruby, but as far as Scala and Java are concerned, you might want to consider taking a look at Akka. It is based on a distributed actor model, which also supports transactions and different levels of fault tolerance. It's probably better to reuse their infrastructure than writing your own distributed fault tolerant runtime from scratch.