1

我们的移动应用程序跟踪用户事件(事件可以有多种类型)

每个报告用户事件及以后的移动设备都可以检索它。

我想写给 Redis 和 Mysql。

当用户请求时:

1. Find on Redis
2. If not on Redis find on Mysql
3. Return the value
4. Keep Redis modified in case value wasnt existed.
5. set expiry policy to each key on redis to avoid out of mem.

问题:

1. Reads: If many users at once requesting information which not existed at Redis  mysql going to be overloaded with Reads (latency).

2. Writes: I am going to have lots of writes into Mysql since every event going to be written to both datasources.

事实:

1. Expecting 10m concurrect users which writes and reads.
2. Need to serv each request with max latency of one second.
3. expecting to have couple of thousands requests per sec.

这种机制有什么解决方案来获得良好的 qos 吗?

3. Is that in any way Lambda architecture solution ? 

谢谢你。

4

1 回答 1

0

抱歉,但此类问题(复杂)在这里很少有现成的答案。太多的未知数。你的预算是多少,你有多少硬件。由于有 1000 万客户同时使用您的服务,因此您的问题是关于硬件,而不是软件。

这里没有关于几个重要要求的任何话:

  1. 什么更重要——一致性可用性
  2. 读/写比率是多少?

读/写比率要求

如果您有 10,000,000 个并发用户,这本身就是问题。但如果你有很多阅读量,它并不像看起来那么糟糕。在这种情况下,您应该注意 mysql 中的正确索引。还要购买具有大量 RAM 的服务器,以至少在 RAM 中保留索引数据。因此,一台服务器可以在 1 秒内容纳 3000-5000 个并发选择查询,而不会出现任何延迟要求问题(我们的一个统计项目在 4 岁的普通硬件上每台服务器最多可容纳 7,000 个选择 rps)。

如果你有很多写入 - 一切都会变得更加复杂。一致性成为主要问题。

一致性与可用性

如果一致性很重要 - 去商店购买带有 SSD 驱动器和现代 CPU 的新服务器。不要忘记购买尽可能多的 RAM。为什么?如果您有很多写入请求,您的 sql 服务器将在每次写入时重建索引。而且您不能不使用索引,因为您的读取请求不会满足延迟要求。在一致性下,我的意思是——如果你写东西,你应该在 1 秒内完成,如果你在写完之后立即读取这些数据——你会在 1 秒内得到实际的书面信息。

你的问题1:

读取:如果多个用户同时请求 Redis 中不存在的信息,则 mysql 将因读取(延迟)而过载。

或众所周知的“缓存未命中”问题。它只有一些解决方案——水平扩展(购买更多硬件)或预缓存。这种情况下的预缓存至少可以在 3 个场景中完成:

  1. 使用非阻塞读取并等待最多一秒钟,而不会从 SQL 服务器查询数据。如果不是,则从 Redis 返回数据。立即更新 Redis 或抛出队列 - 如你所愿。
  2. 尽可能快地使用阻塞/非阻塞从 Redis 读取和返回数据,但每次准备好的查询都将 jub 推送到队列中以更新 Redis 中的缓存数据(也可能会通知应用程序它应该在一段时间后重新查询数据)。
  3. 始终从 Redis 读取/写入,但在每次写入请求时在队列中注册作业以更新 SQL 中的数据。

他们每个人都是妥协:

  1. 高可用但一致性受损,Redis 是 LRU 缓存。
  2. 高可用但一致性受损,Redis 是 LRU 缓存。
  3. 高可用性和一致性,但需要大量内存用于 Redis。

写入:我将对 Mysql 进行大量写入,因为每个事件都将写入两个数据源。

再次提起妥协。很多写入都依赖于硬件。所以购买更多或使用队列来等待写入。所以再次可用性与一致性。

事件跟踪意味着(通常)您可以接近实时但不是实时地返回数据。例如,更新磁盘(mysql)上的数据有 1-10 秒的延迟,为写入/读取服务请求保持 1 秒的延迟。因此,它结合了 1/2/3(或其他一些)技术用于数据证明:

  • 在 Redis 中使用 LRU,不要使用 expire。很多过期键 - 问题就是这样。所以我们不能确保我们节省内存。
  • 使用队列来预热 Redis 中丢失的键。
  • 使用队列将数据从 Redis 服务器写入 mysql 服务器。
  • 使用附加请求来更新来自缓存缺失情况的客户端大小的数据。
于 2015-12-27T14:59:01.793 回答