频道

时间:2016-05-14 09:22:38

标签: erlang elixir phoenix-framework

我正在使用凤凰框架构建一个应用程序,该框架将使用数千个频道,用户将每隔一秒发送长,lat信息的消息。

所以,我每秒钟会收到数千封邮件。

问题是,我如何存储我收到的每条消息? 请耐心跟我描述一下我对此的想法,因为我正在考虑以下选项来处理存储到DB中的消息:

  1. 使用相同的连接过程将消息存储到DB中。

    可能的警告: 这是否会影响频道的延迟时间和性能?

  2. 为每个频道创建一个数据库专用流程来存储其消息。

    可能的警告: 然后,如果我有100'000频道,我将需要另外100'000进程来存储消息,这很好吗?考虑到erlang进程简洁且便宜?

  3. 为所有频道创建一个数据库进程,然后来自任何频道的每封邮件将排队,然后由此单独的数据库进程存储。

    可能的警告: 存储数千个频道的所有消息的一个过程,消息队列会变高,会慢吗?

  4. 那么,推荐的方法是存储来自数千个频道的每秒消息?

    修改

    我将使用dynamo db,它将扩展以轻松处理数千个并发请求。

1 个答案:

答案 0 :(得分:2)

最重要的问题是连接通道中的请求是否可以在写入数据库之前完成。您需要考虑如果连接进程响应回客户端会发生什么,并且DB发生了某些事情,以便编写它。如果数据丢失是可接受的,那么DB访问可以异步完成,如果不是,那么它需要是同步的,例如,只有在DB确认已存储请求后才响应客户端。

如果数据可以异步存储到数据库,那么最好生成一个新进程来完成它或将它添加到队列(2和3)。如果数据必须同步存储,那么在同一过程(1)中处理它更容易。请注意,如果在不同的进程中处理数据库写入且消息大小很大,则必须在进程之间复制请求,这可能会影响性能。

可以提高异步写入的可靠性,例如在将请求写入数据库之前将请求存储在某处,然后回复客户端,然后尝试完成数据库写入,如果DB关闭,则可以重试。但它使这一点复杂化。

您还需要确定瓶颈,架构中最慢的部分是什么。如果数据库然后,如果您为数据库创建一个请求队列或者为每个连接创建一个新进程并不重要,那么请求将堆积在该单个进程的内存中或者数量为创建过程。

我可能会确定数据库可以处理多少并行连接而不会过多地牺牲延迟并创建一个处理请求的进程池。然后我会创建一个队列来将请求分派给那些池化的进程。为了处理更大的消息,我将从队列中获取一个令牌(写入权限)并直接连接到DB以避免过多地复制消息。如果以后发现任何瓶颈,那么该架构将更容易扩展,例如,持久存储传入的消息,然后才能将数据写入数据库,或者在数据库过载时平衡对其他节点的请求。