0

0

使用 Redis 实现 SQL 伸缩

php中文网

php中文网

发布时间:2016-06-07 16:43:31

|

1210人浏览过

|

来源于php中文网

原创

我喜欢Redis。这是目前的技术当中唯一让你奇怪为什么需要这么长时间编译它的技术。可预测的,高性能并且适应性强,这是我过去几年

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

 

一个多星期前,我在 Python Nordeste 上作了主题演讲。某种程度上而言我只能作一些快速的总结,我决定去找一些黑客来探讨大量使用Sentry,特别是Redis技术。这篇文章是一个5分钟讨论的扩充。

缓解行之间的争夺

 

我们采用了早在哨兵发展的东西是什么成为著名的sentry.buffers。这是一个简单的系统,使我们能够实现非常有效的缓冲计数器,一个简单的上次写入赢的策略。重要的是要注意,我们完全与此几乎杜绝任何形式的耐用性(这是非常可以接受的哨兵的工作方式)。

该操作是相当简单的,每当一个更新进来,我们做到以下几点:

1.创建绑定到给定实体散列键

2.增量'反'使用HINCRBY

3.HEST各种不同LWW数据(如“最后一次见到”)

4.ZADD散列键到'挂起'使用当前时间戳设置

现在,每个刻度(在哨兵的情况下,这是10秒),我们要转储这些缓冲区和扇出的写入。这看起来像下面这样:

1.开始使用ZRANGE所有键

2. 火了一个作业分成RabbitMQ的每一个悬而未决的关键

3. ZREM给定的键

现在RabbitMQ作业将能够读取和清除哈希表,和“悬而未决”更新已经弹出了一套。有几件事情需要注意:

  • 在下面我们想要只弹出一个设置的数量的例子中我们将使用一组排序(举例来说我们需要那100个旧集合)。

  • 假使我们为了处理一个键值来结束多道排序的作业,这个人会得到no-oped由于另一个已经存在的处理和清空哈希的过程。

  • 我们有了这个处理问题的模型之后,能够确保“大部分情况下”每次在SQL中只有一行能够被马上更新,而这样的处理方式减轻了我们能够预见到的锁问题。考虑到将会处理一个突然产生且所有最终组合在一起进入同一个计数器的数据的场景,这种策略对Sentry用处很多。

    速度限制

    它的逻辑相当直接,如同下面展示的那般:

    def incr_and_check_limit(user_id, limit):

    key = '{user_id}:{epoch}'.format(user_id, int(time() / 60))

     

    pipe = redis.pipeline()

    pipe.incr(key)

    pipe.expire(key, 60)

    current_rate, _ = pipe.execute()

     

    return int(current_rate) > limit

    我们所阐明的限制速率的方法是 Redis在高速缓存服务上最基本的功能之一:增加空的键字。在高速缓存服务中实现同样的行为可能最终使用这种方法:

    def incr_and_check_limit_memcache(user_id, limit):

    key = '{user_id}:{epoch}'.format(user_id, int(time() / 60))

     

    if cache.add(key, 0, 60):

    return False

     

    current_rate = cache.incr(key)

     

    return current_rate > limit

    事实上我们最终采取这种策略可以使哨兵追踪不同事件的短期数据。在这种情况下,我们通常对用户数据进行排序以便可以在最短的时间内找到最活跃用户的数据。

    基本锁

    虽然Redis的是可用性不高,我们的用例锁,使其成为工作的好工具。我们没有使用这些在哨兵的核心了,但一个示例用例是,我们希望尽量减少并发性和简单无操作的操作,如果事情似乎是已经在运行。这对于可能需要执行每隔一段时间类似cron任务非常有用,但不具备较强的协调。
    在Redis的这样使用SETNX操作是相当简单的:

    from contextlib import contextmanagerr = Redis()@contextmanagerdef lock(key, nowait=True):

    while not r.setnx(key, '1'):

    if nowait:

    raise Locked('try again soon!')

    sleep(0.01)

     

    # limit lock time to 10 seconds r.expire(key, 10)

     

    # do something crazy yield

     

    # explicitly unlock r.delete(key)

    而锁()内的哨兵利用的memcached的,但绝对没有理由我们不能在其切换到Redis。

    时间序列数据

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

    如下所示:

    {

    "::": {

    "":

    4种CSS3超酷移动手机滑动隐藏侧边栏菜单特效
    4种CSS3超酷移动手机滑动隐藏侧边栏菜单特效

    这是一组共4种效果非常炫酷的CSS3移动手机滑动隐藏侧边栏菜单特效。这四种效果分别是:默认的点击滑动侧边栏菜单效果、带3D transforms的滑动侧边栏效果、文字缩放和淡入淡出效果的滑动侧边栏以及使用translate来实现滑动侧边栏的效果

    下载

    }}

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

    {

    "1:1399958363:0": {

    "1": 53,

    "2": 72,

    }}

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

    "1:1399958363:0:1": 53

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

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

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

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

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

    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)

    归结如下:

  • 生成所必须的键。

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

  • 简单的选择

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    俄罗斯Yandex引擎入口
    俄罗斯Yandex引擎入口

    2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

    178

    2026.01.28

    包子漫画在线官方入口大全
    包子漫画在线官方入口大全

    本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

    35

    2026.01.28

    ao3中文版官网地址大全
    ao3中文版官网地址大全

    AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

    79

    2026.01.28

    php怎么写接口教程
    php怎么写接口教程

    本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

    2

    2026.01.28

    php中文乱码如何解决
    php中文乱码如何解决

    本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

    4

    2026.01.28

    Java 消息队列与异步架构实战
    Java 消息队列与异步架构实战

    本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

    8

    2026.01.28

    Python 自然语言处理(NLP)基础与实战
    Python 自然语言处理(NLP)基础与实战

    本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

    24

    2026.01.27

    拼多多赚钱的5种方法 拼多多赚钱的5种方法
    拼多多赚钱的5种方法 拼多多赚钱的5种方法

    在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

    122

    2026.01.26

    edge浏览器怎样设置主页 edge浏览器自定义设置教程
    edge浏览器怎样设置主页 edge浏览器自定义设置教程

    在Edge浏览器中设置主页,请依次点击右上角“...”图标 > 设置 > 开始、主页和新建标签页。在“Microsoft Edge 启动时”选择“打开以下页面”,点击“添加新页面”并输入网址。若要使用主页按钮,需在“外观”设置中开启“显示主页按钮”并设定网址。

    72

    2026.01.26

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    SQL 教程
    SQL 教程

    共61课时 | 3.6万人学习

    进程与SOCKET
    进程与SOCKET

    共6课时 | 0.4万人学习

    SQL优化与排查(MySQL版)
    SQL优化与排查(MySQL版)

    共26课时 | 2.3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号