我的编程空间,编程开发者的网络收藏夹
学习永远不晚

利用Redis实现SQL伸缩的方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

利用Redis实现SQL伸缩的方法

这篇文章主要介绍了利用Redis实现SQL伸缩的方法,包括讲到了锁和时间序列等方面来提升传统数据库的性能,需要的朋友可以参考下。

缓解行竞争

我们在Sentry开发的早起采用的是sentry.buffers。 这是一个简单的系统,它允许我们以简单的Last Write Wins策略来实现非常有效的缓冲计数器。 重要的是,我们借助它完全消除了任何形式的耐久性 (这是Sentry工作的一个非常可接受的方式)。

操作非常简单,每当一个更新进来我们就做如下几步:

创建一个绑定到传入实体的哈希键(hash key) 使用HINCRBY使计数器值增加 HSET所有的LWW数据(比如 "最后一次见到的") 用当前时间戳ZADD哈希键(hash key)到一个"挂起" set

现在每一个时间刻度 (在Sentry中为10秒钟) 我们要转储(dump)这些缓冲区并且扇出写道(fanout the writes)。 看起来像下面这样:

使用ZRANGE获取所有的key 为每一个挂起的key发起一个作业到RabbitMQ

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

在下面我们想要只弹出一个设置的数量的例子中我们将使用一组排序(举例来说我们需要那100个旧集合)。 假使我们为了处理一个键值来结束多道排序的作业,这个人会得到no-oped由于另一个已经存在的处理和清空哈希的过程。 该系统能够在许多Redis节点上不断扩展下去仅仅是通过在每个节点上安置把一个'悬置'主键来实现。

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

速度限制

出于哨兵的局限性,我们必须终结持续的拒绝服务攻击。我们通过限制连接速度来应对这种问题,其中一项是通过Redis支持的。这无疑是在sentry.quotas范围内更直接的实现。

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


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存储数据,它也是使用计数器的简单范例。

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


{ 
 
  "<type enum>:<epoch>:<shard number>": { 
 
    "<id>": <count> 
 
  }} 

因此在这种状况,我们需要追踪事件的数目。事件类型映射到枚举类型"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) 

归结如下:

生成所必须的键。 使用工作区,提取所有连接操作的最小结果集(Nydus负责这些)。 给出结果,并且基于指定的时间间隔内和给定的键值将它们映射到当前的存储区内。

以上就是如何利用Redis实现SQL伸缩的方法,希望对大家的学习有所帮助。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

利用Redis实现SQL伸缩的方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

利用Redis实现SQL伸缩的方法

这篇文章主要介绍了利用Redis实现SQL伸缩的方法,包括讲到了锁和时间序列等方面来提升传统数据库的性能,需要的朋友可以参考下。 缓解行竞争 我们在Sentry开发的早起采用的是sentry.buffers。 这是一个简单的系统,它允许我们
2022-06-04

利用Redis实现SQL伸缩的方法简介

缓解行竞争 我们在Sentry开发的早起采用的是sentry.buffers。 这是一个简单的系统,它允许我们以简单的Last Write Wins策略来实现非常有效的缓冲计数器。 重要的是,我们借助它完全消除了任何形式的耐久性 (这是Se
2022-06-04

怎么在Android中利用ScrollView 实现一个伸缩放大效果

这篇文章给大家介绍怎么在Android中利用ScrollView 实现一个伸缩放大效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。核心的控件就是下面的这段代码:package com.kokjuis.travel.c
2023-05-31

Redis使用Bitmap的方法实现

目录1. Bitmap 是什么2. 占用存储空间3. 命令3.1 SETBIT3.2 GETBIT3.3 BITCOUNT3.4 BITOP3.5 BITPOS1. Bitmap 是什么Bitmap(也称为位数组或者位向量等)是一种实现对
2023-01-28

Python3压缩和解压缩的实现方法

这篇文章主要为大家展示了Python3压缩和解压缩的实现方法,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“Python3压缩和解压缩的实现方法”这篇文章吧。python可以做什么Python是一种
2023-06-06

如何用 C++ 函数设计和实现可伸缩的并发系统?

通过遵循原子性、线程安全性、可重用性原则,并利用线程、锁、原子变量等机制,c++++ 提供了创建可扩展并发系统所需的强大特性,例如并行求和等实战案例中所示。利用 C++ 函数构建可扩展的并发系统引言在现代软件开发中,并发性对于处理繁重的计
如何用 C++ 函数设计和实现可伸缩的并发系统?
2024-04-27

css首行缩进的实现方法

这篇文章主要为大家展示了css首行缩进的实现方法,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“css首行缩进的实现方法”这篇文章吧。css是什么意思css是一种用来表现HTML或XML等文件样式的
2023-06-06

JavaScript实现图像压缩的方法

使用JavaScript和canvas压缩图像可以使用canvas的drawImage()方法将图像绘制到canvas上,然后使用toDataURL()方法将图像转换为DataURL形式,这篇文章主要介绍了JavaScript图像压缩的相关资料,需要的朋友可以参考下
2023-01-11

css实现禁止缩放的方法

这篇文章主要介绍“css实现禁止缩放的方法”,在日常操作中,相信很多人在css实现禁止缩放的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”css实现禁止缩放的方法”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-14

Python利用第三方模块实现压缩css文件

在 Python 中可以使用多种方法来压缩 CSS 文件。其中一种流行的方法是使用 csscompressor 库,这个库可以帮助你压缩 CSS 代码,下文就来和大家详细聊聊
2023-01-28

Android实现zip文件压缩及解压缩的方法

本文实例讲述了Android实现zip文件压缩及解压缩的方法。分享给大家供大家参考。具体如下: DirTraversal.java如下:package com.once; import java.io.File; import java.u
2022-06-06

利用yum安装Redis的方法详解

介绍 Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set ?有序集合)和hash(哈希类型)
2022-06-04

LRUCache的实现原理及利用python实现的方法

简介 LRU(Least Recently Used)最近最少使用,最近有时间和空间最近的歧义,所以我更喜欢叫它近期最少使用算法。它的核心思想是,如果一个数据被访问过,我们有理由相信它在将来被访问的概率就越高。于是当LRU缓存达到设定的最大
2022-06-04

python语句和缩进的实现方法

这篇文章主要介绍了python语句和缩进的实现方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。python可以做什么Python是一种编程语言,内置了许多有效的工具,Pyt
2023-06-14

编程热搜

目录