我喜欢Redis。这是目前的技术当中唯一让你奇怪为什么需要这么长时间编译它的技术。可预测的,高性能并且适应性强,这是我过去几年越来越多使用它的原因。Sentry主要在PostgreSQL上运行已经不是秘密(尽管目前它还依赖于一系列其它技术) 一个多星期前,我在 Python Nordeste 上作了主题演讲。某种程度上而言我只能作一些快速的总结,我决定去找一些黑客来探讨大量使用Sentry,特别是Redis技术。这篇文章是一个5分钟讨论的扩充。 缓解行竞争我们在Sentry开发的早起采用的是sentry.buffers。 这是一个简单的系统,它允许我们以简单的Last Write Wins策略来实现非常有效的缓冲计数器。 重要的是,我们借助它完全消除了任何形式的耐久性 (这是Sentry工作的一个非常可接受的方式)。 操作非常简单,每当一个更新进来我们就做如下几步:
现在每一个时间刻度 (在Sentry中为10秒钟) 我们要转储(dump)这些缓冲区并且扇出写道(fanout the writes)。 看起来像下面这样:
现在RabbitMQ作业将能够读取和清除哈希表,和“悬而未决”更新已经弹出了一套。有几件事情需要注意:
我们有了这个处理问题的模型之后,能够确保“大部分情况下”每次在SQL中只有一行能够被马上更新,而这样的处理方式减轻了我们能够预见到的锁问题。考虑到将会处理一个突然产生且所有最终组合在一起进入同一个计数器的数据的场景,这种策略对Sentry用处很多。 速度限制出于哨兵的局限性,我们必须终结持续的拒绝服务攻击。我们通过限制连接速度来应对这种问题,其中一项是通过Redis支持的。这无疑是在 sentry.quotas范围内更直接的实现。 它的逻辑相当直接,如同下面展示的那般:
我们所阐明的限制速率的方法是 Redis在高速缓存服务上最基本的功能之一:增加空的键字。在高速缓存服务中实现同样的行为可能最终使用这种方法:
事实上我们最终采取这种策略可以使哨兵追踪不同事件的短期数据。在这种情况下,我们通常对用户数据进行排序以便可以在最短的时间内找到最活跃用户的数据。 基本锁虽然Redis的是可用性不高,我们的用例锁,使其成为工作的好工具。我们没有使用这些在哨兵的核心了,但一个示例用例是,我们希望尽量减少并发性和简单无操作的操作,如果事情似乎是已经在运行。这对于可能需要执行每隔一段时间类似cron任务非常有用,但不具备较强的协调。
而锁()内的哨兵利用的memcached的,但绝对没有理由我们不能在其切换到Redis。 |