设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客
LUPA开源社区 首页 业界资讯 技术文摘 查看内容

使用Redis实现SQL伸缩

2014-8-18 15:34| 发布者: joejoe0332| 查看: 3941| 评论: 0|原作者: 白文, 学习者8, 无若, ZICK_ZEON, 刘家华|来自: oschina

摘要: 我喜欢Redis。这是目前的技术当中唯一让你奇怪为什么需要这么长时间编译它的技术。可预测的,高性能并且适应性强,这是我过去几年越来越多使用它的原因。Sentry主要在PostgreSQL上运行已经不是秘密(尽管目前它还依 ...


时间序列数据

  近来我们创造一个新的机制在Sentry(包含在sentry.tsdb)存储时间序列数据。这是受RRD模型启发,特别是Graphite。我们期望一个快速简单的方式存储短期(比如一个月)时间序列数,以便于处理高速写入数据,特别是在极端情况下计算潜在的短期速率。尽管这是第一个模型,我们依旧期望在Redis存储数据,它也是使用计数器的简单范例。


  在目前的模型中,我们使用单一的hash map来存储全部时间序列数据。例如,这意味所有数据项在都将同一个哈希键拥有一个数据类型1秒的生命周期。如下所示:

1
2
3
4
{
    "<type enum>:<epoch>:<shard number>": {
        "<id>": <count>
    }}


  因此在这种状况,我们需要追踪事件的数目。事件类型映射到枚举类型"1".该判断的时间是1s,因此我们的处理时间需要以秒计。散列最终看起来是这样的:

1
2
3
4
5
{
    "1:1399958363:0": {
        "1": 53,
        "2": 72,
    }}


  一个可修改模型可能仅使用简单的键并且仅在存储区上增加一些增量寄存器。

   "1:1399958363:0:1": 53


  我们选择哈希映射模型基于以下两个原因:

  • 我们可以将所有的键设为一次性的(这也可能产生负面影响,但是目前为止是稳定的)

  • 大幅压缩键值,这是相当重要的处理


  此外,离散的数字键允许我们在将虚拟的离散键值映射到固定数目的键值上,并在此分配单一存储区(我们可以使用64,映射到32个物理结点上)


  现在通过使用 Nydus和它的map()(依赖于一个工作区)(),数据查询已经完成。这次操作的代码是相当健壮的,但幸好它并不庞大。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def get_range(self, model, keys, start, end, rollup=None):
    """    To get a range of data for group ID=[1, 2, 3]:    Start and end are both inclusive.    >>> now = timezone.now()    >>> get_keys(tsdb.models.group, [1, 2, 3],    >>>          start=now - timedelta(days=1),    >>>          end=now)    """
    normalize_to_epoch = self.normalize_to_epoch
    normalize_to_rollup = self.normalize_to_rollup
    make_key = self.make_key
 
    if rollup is None:
        rollup = self.get_optimal_rollup(start, end)
 
    results = []
    timestamp = end
    with self.conn.map() as conn:
        while timestamp >= start:
            real_epoch = normalize_to_epoch(timestamp, rollup)

            norm_epoch = normalize_to_rollup(timestamp, rollup)
 
            for key in keys:
                model_key = self.get_model_key(key)
                hash_key = make_key(model, norm_epoch, model_key)
                results.append((real_epoch, key, conn.hget(hash_key, model_key)))
 
            timestamp = timestamp - timedelta(seconds=rollup)
 
    results_by_key = defaultdict(dict)
    for epoch, key, count in results:
        results_by_key[key][epoch] = int(count or 0)
 
    for key, points in results_by_key.iteritems():
        results_by_key[key] = sorted(points.items())
    return dict(results_by_key)


  归结如下:

  • 生成所必须的键。

  • 使用工作区,提取所有连接操作的最小结果集(Nydus负责这些)。

  • 给出结果,并且基于指定的时间间隔内和给定的键值将它们映射到当前的存储区内。



简单的选择

  我是一个喜欢用简单的方案解决问题的人,在这个范畴里使用Redis无疑是很适合的。它的文档是那样让人惊讶,那是因为(阅读)其文档的门槛非常的低。虽然他也有折衷(主要是如果你使用持久化),但是他们工作地很好并且比较直观。


  那么Redis为您解决什么问题呢?


酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部