Redis分片

本文是我们学院课程的一部分,标题为Redis NoSQL键值存储 。

这是Redis的速成班。 您将学习如何安装Redis并启动服务器。 此外,您将在Redis命令行中乱七八糟。 接下来是更高级的主题,例如复制,分片和集群,同时还介绍了Redis与Spring Data的集成。 在这里查看 !

目录

1.简介 2.何时使用分片(分区) 3.分片(分区)方案 4.分片(分区)实现 5.计划分片(分区) 6.分片(分区)和复制 7.用Twemproxy进行分片(分区) 8.接下来

1.简介

我们正在处理的数据量每天都在成倍增长。 当必要的数据无法容纳在内存中,甚至物理存储空间不足时,我们经常面临单个盒子的硬件限制。 多年以来,这些问题导致业界开发了可以克服此类限制的数据分片(或数据分区)解决方案。

在Redis中,数据分片(分区)是一种在多个Redis实例之间拆分所有数据的技术,这样每个实例将仅包含密钥的一个子集。 通过添加越来越多的实例并将数据划分为较小的部分(碎片或分区),这样的过程可以减轻数据的增长。 不仅如此,这还意味着越来越多的计算能力可用于处理数据,有效地支持水平缩放。

尽管并非所有解决方案都是双赢的,但仍需要权衡取舍:通过在多个实例之间拆分数据,查找特定键(或多个键)的问题成为一个问题。 这就是分片(分区)方案的用武之地:应该按照一些一致或固定的规则对数据进行分片(分区),以便对同一密钥的写入和读取操作应转到拥有(拥有)此密钥的Redis实例。

本教程的材料基于与分片和分区有关的出色Redis文档: http : //redis.io/topics/partitioning

2.何时使用分片(分区)

根据Redis文档( http://redis.io/topics/partitioning ),如果要执行以下操作,应考虑对数据进行分片(分区):

  • 使用多台计算机的内存来管理更大的数据库(否​​则,您将受限于单台计算机可以支持的内存量)
  • 扩展多个CPU,多个计算机的计算能力,并利用它们的网络带宽

如果您认为现在不存在数据扩展问题,则可能会在不久的将来遇到问题,因此最好做好准备并提前考虑(请参阅规划分片(分区) )。 但在这样做之前,请考虑分片(分区)带来的复杂性和缺点:

  • 通常不支持涉及多个键的操作。 例如,如果两个集合( SINTER )存储在映射到不同Redis实例的键中,则不可能直接执行它们之间的交集。
  • 涉及映射到不同Redis实例的多个密钥的事务是不可能的。
  • 分区是基于键的,因此无法使用单个大键(很大的排序集或列表)对数据集进行分片(分区)。
  • 备份和持久管理要复杂得多:您必须处理多个RDB / AOF文件,备份涉及来自许多实例的RDB文件的聚合(合并)。
  • 除非您对此进行了计划,否则在运行时添加和删除实例可能会导致数据失衡(请参阅规划分片(分区) )。

3.分片(分区)方案

Redis可以使用几种经过战斗验证的分片(分区)方案,具体取决于您的数据模式。

  • 范围划分
    通过将对象范围映射到特定的Redis实例中来完成。 例如,假设我们正在存储一些用户数据,并且每个用户都有其唯一的标识符(ID)。 在我们的分区方案中,我们可以定义ID为0到10000的用户将进入实例Redis 1,而ID为10001到20000的用户将进入实例Redis 2,依此类推。 该方案的缺点是,范围和实例之间的映射应该被维护,并且应该与Redis中保留的对象(用户,产品等)的种类一样多的映射。
  • 哈希分区
    该方案适用于任何密钥,但涉及哈希函数 :此函数应将密钥名称映射到某个数字。 假设我们有这样一个函数(我们称其为hash_func ),这样的方案就是这样的:
    • 取得键名,并使用hash_func将其映射到数字

    哈希函数的选择非常重要。 良好的哈希函数可确保密钥在所有Redis实例上平均分布,因此不会在任何单个实例上建立过多的密钥。

  • 一致性哈希
    它是hash partitioning的一种高级形式,被许多解决方案用于数据分片(分区)。

4.分片(分区)实现

从实现的角度来看,根据应用程序的体系结构,有几种可能的数据分片(分区)实现:

  • 客户端分区
    客户端直接选择正确的实例来写入或读取给定的密钥。
  • 代理辅助分区
    客户端将请求发送到支持Redis协议的代理,而不是直接将请求发送到正确的Redis实例。 代理将确保根据配置的分区方案将请求转发到正确的Redis实例,并将答复发送回客户端(最著名的实现是Twitter的Twemproxy , https://github.com/twitter/ twemproxy )。
  • 查询路由
    客户端将查询发送到随机Redis实例,该实例将确保将查询转发到正确的实例。 查询路由的混合形式假定客户端重定向到正确的实例(但是查询不会直接从一个Redis实例转发到另一个实例),并将在本教程的第5部分“ Redis群集”中介绍 。

5.计划分片(分区)

如前所述,一旦您开始在许多Redis实例之间使用数据分片(分区),则在运行时添加和删除实例可能会很困难。 您经常会在Redis中使用的一种技术称为Presharding ( http://redis.io/topics/partitioning )。

预分片的想法是从一开始就以许多实例开始(但实际节点/服务器的数量很少或很少)。 自开始以来,实例的数量可能会有所不同并且可能会很大(对于大多数用例而言,32或64个实例就足够了)。 由于Redis非常轻巧,因此完全有可能在单个服务器上运行64个Redis实例。

这样,随着数据存储需求的增长以及需要更多Redis节点/服务器来处理它,可以将实例从一台服务器移动到另一台服务器。 例如,如果您有一台服务器并添加了另外一台服务器,则应将第一台服务器的一半Redis实例移到第二台服务器。 当每个服务器/节点上有一个Redis实例时,此技巧可能会一直持续下去。

但是要记住一件事:如果将Redis用作数据的内存缓存(而不是持久性数据存储),则可能不需要使用预分片。 一致的散列实现通常能够在运行时处理新的或删除的实例。 例如,如果给定密钥的首选实例不可用,则其他实例将使用该密钥。 或者,如果添加新实例,则新密钥的一部分将存储在该新实例上。

6.分片(分区)和复制

在许多实例之间分片(分区)数据并不能解决数据安全和冗余问题。 如果其中一个分片(分区)由于硬件故障而死,而您没有备份来还原数据,则意味着您将永远丢失数据。

这就是为什么分片(分区)与复制并存的原因。 如果将Redis用作持久性数据存储,则最好为不同服务器/节点上的每个分片(分区)配置至少一个副本。 这可能会使您的容量需求增加一倍,但确保数据安全就显得更为重要。

复制的配置与本教程第3部分“ Redis复制 ”中介绍的配置没有任何不同。

7.用Twemproxy进行分片(分区)

Twemproxy (也称为nutcracker )是由Twitter( https://github.com/twitter/twemproxy )开发和开源的,它是Redis的广泛使用,非常快速和轻量级的代理。 尽管它具有许多功能,但我们要介绍的功能与其向Redis添加分片(分区)的能力有关:

  • 在多台服务器之间自动分片数据
  • 支持多种哈希模式,包括一致的哈希和分布

Twemproxynutcracker )非常易于安装和配置。 本教程的最新版本是0.3.0 ,可以从http://code.google.com/p/twemproxy/downloads/list下载。 安装非常简单。

  1. 下载
    wget http://twemproxy.googlecode.com/files/nutcracker-0.3.0.tar.gz
  2. 解压缩档案
    tar xfz nutcracker-0.3.0.tar.gz
  3. 构建(您需要的唯一预装软件包是gccmake )。
    cd nutcracker-0.3.0
    ./configure
    make
  4. 安装
    sudo make install

缺省情况下, twemproxynutcracker )将位于/usr/local/sbin/nutcracker 。 安装后,最重要的部分(但是非常简单)是其配置。

Twemproxynutcracker )使用YAML作为配置文件格式( http://www.yaml.org/ )。 在twemproxynutcracker )支持的许多设置中,我们将选择与分片(分区)相关的设置。

设置 听:名称:端口| ip:端口
描述 此服务器池的侦听地址和端口( name:portip:port )。
听:127.0.0.1:22121

表格1

设置 哈希:<功能>
描述 哈希函数的名称。 可能的值为:

- 一次一个

– md5( http://en.wikipedia.org/wiki/MD5 )

– crc16( http://en.wikipedia.org/wiki/Cyclic_redundancy_check )

– crc32(与libmemcached兼容的crc32实现)

– crc32a(根据规范正确的crc32实现)

– fnv1_64( http://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function )

– fnv1a_64( http://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function )

– fnv1_32( http://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function )

– fnv1a_32( http://en.wikipedia.org/wiki/Fowler–Noll–Vo_hash_function )

– hsieh( http://www.azillionmonkeys.com/qed/hash.html )

–杂音( http://en.wikipedia.org/wiki/MurmurHash )

–詹金斯( http://en.wikipedia.org/wiki/Jenkins_hash_function )

杂凑:fnv1a_64

表2

设置 分布:<模式>
描述 密钥分发模式(请参阅http://en.wikipedia.org/wiki/Consistent_hashing )。 可能的值为:

–凯塔玛

–模数

–随机

分布:ketama

表3

设置 redis:是|否
描述 一个布尔值,它控制服务器池是否使用Redis或Memcached协议。 由于我们将仅使用Redis,因此此设置应设置为true 。 默认为false
redis:是的

表4

设置 auto_eject_hosts:true |
描述 一个布尔值,用于控制服务器连续失败server_failure_limit次后是否应暂时退出服务器。 默认为false
auto_eject_hosts:否

表5

设置 server_retry_timeout:<毫秒>
描述 auto_eject_host设置为true时,在临时弹出的服务器上重试之前等待的超时值(以毫秒为单位)。 默认值为30000毫秒。
server_retry_timeout:30000

表6

设置 server_failure_limit:<数字>
描述 auto_eject_host设置为true时,服务器上导致其暂时退出的连续失败次数。 默认为2
server_failure_limit:2

表7

设置 服务器:

名称:端口:重量| ip:端口:重量

名称:端口:重量| ip:端口:重量

描述 特定服务器池的服务器地址,端口和权重( name:port:weightip:port:weight)的列表。
服务器:

127.0.0.1:6379:1

127.0.0.1:6380:1

表8

我们将使用三个Redis实例(服务器池)构建一个简单的拓扑,并在它们前面配置twemproxynutcracker ),如下图所示:

图1.具有Redis服务器池配置的Twemproxy,包含三个实例。

图1. Twemproxy和Redis服务器池配置由三个实例组成

twemproxynutcracker )发行版中的conf/nutcracker.yml文件是寻找不同配置示例的良好起点。 至于示范,我们将与下面开始sharded服务器池,反映了上面显示的拓扑结构。

文件nutcracker-sharded.yml

sharded:listen: 127.0.0.1:22122hash: fnv1a_64distribution: ketamaauto_eject_hosts: trueredis: trueserver_retry_timeout: 2000server_failure_limit: 2servers:- 127.0.0.1:6380:1- 127.0.0.1:6381:1- 127.0.0.1:6382:1

sharded服务器池使用ketama与关键散列器设置为密钥分发一致性哈希fnv1a_64

在开始之前twemproxynutcracker ),我们应该有三个Redis的情况下,并在端口6380,63816382上运行。

redis-server --port 6380
redis-server --port 6381
redis-server --port 6382

之后,可以使用以下命令启动带有示例配置的twemproxynutcracker )实例:

nutcracker -c nutcracker-sharded.yml
图2. Twemproxy(胡桃夹子)已成功启动。

图2. Twemproxy(胡桃夹子)已成功启动

验证分片(分区)的最简单方法是连接到twemproxynutcracker ),存储一对键/值对,然后尝试从每个Redis实例中获取所有存储的键:每个键应返回一个且只有一个例如,其他人应该返回( nil )。 虽然,从twemproxynutcracker )查询相同的键将始终twemproxy先前存储的值。 根据我们的样本配置, twemproxynutcracker )正在侦听端口22122 ,可以使用常规redis-cli工具进行连接。 三个键userkeysomekeyanotherkey将设置为一些值。

图3.在Twemproxy(胡桃夹子)中设置几个键/值对,并验证它们是否已存储。

图3.在Twemproxy(胡桃夹子)中设置几个键/值对并验证它们是否已存储

现在,如果我们从twemproxynutcracker )服务器池中查询每个单独的Redis实例,则某些实例(而不是其他实例)将解析某些键( userkeysomekeyanotherkey )。

图片4. Redis#1没有存储密钥。

图4. Redis#1没有存储密钥

图片5. Redis#2仅存储了一个关键用户密钥。

图5. Redis的#2仅具有一个键userkey存储

图片6. Redis#3有两个一个密钥,一个是密钥,另一个是另一个密钥。

图6. Redis#3有两个一个密钥,一个是somekeyanotherkey另一个key

可能会提出一个有趣的问题:为什么密钥以这种方式存储? 答案是配置的hash function :密钥在服务器池中的所有Redis实例中一致地分布。 但是,为了获得平衡的(均匀或随机)分布,应根据应用程序使用的键命名模式非常仔细地选择配置的hash function 。 如我们的示例所示,密钥并非在所有实例中均匀分布(第一个实例没有任何内容,第二个实例有一个密钥,第三个实例有两个密钥)。

最后的注意事项:尽管twemproxynutcracker )确实支持Redis协议,但由于“ 何时使用分片(分区)”部分中讨论的限制,因此不支持所有命令。

有关twemproxynutcracker )的更多详细信息,请参阅https://github.com/twitter/twemproxy ,它提供了许多不错的最新文档。

8.接下来

在本节中,我们仅介绍了一种如何在Redis中处理分片(分区)的方法。 接下来的第5部分 , Redis群集 ,我们将发现替代解决方案。

翻译自: https://www.javacodegeeks.com/2015/09/redis-sharding.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Openstack入坑指南

什么是云计算 概念 云计算是一种基于互联网的计算方式&#xff0c;通过这种方式&#xff0c;共享的软硬件资源和信息&#xff0c;可以按需求提供给计算机和其他设备。用户不需要了解”云“中的基础设施细节&#xff0c;不必具有相应的专业知识&#xff0c;也无需直接控制。云计…

Akka型演员:探索接收器模式

在上一篇文章中&#xff0c;我们研究了Akka Typed提供的一些基本功能。 在本文和下一篇文章中&#xff0c;我们将更进一步地了解一些其他功能&#xff0c;并通过查看Akka Typed提供的两种不同模式来做到这一点&#xff1a;Receiver和Receptionist模式。 如果您是Akka Typed的新…

读书笔记 - 《乌合之众》

以往的随笔都是胡乱写两句&#xff0c;目的主要是为了督促自己尽快把堆积如山的书籍清理掉&#xff0c;但这次值得花几分钟真的写几句。其实实在都想不起来怎么会买它&#xff0c;这次偶然拿起这本书也是因为它很薄&#xff0c;读大部头读得累了放松一下&#xff0c;没想到居然…

MATLAB如何用循环分割,利用Matlab进行分割提取浮游生物

我试图从扫描图像中提取浮游生物.大纲也不错,但是,现在我不知道如何提取图像,因此可以单独保存每个浮游生物.我尝试使用标签,但是有很多噪音,它标出了每一个规格.我想知道是否有更好的方法来做到这一点.这是我的代码&#xff1a;I imread(plankton_2.jpg);figure, imshow(I), …

saxparser_使用SaxParser和完整代码进行XML解析

saxparserSAX解析器使用回调函数&#xff08;org.xml.sax.helpers.DefaultHandler&#xff09;通知客户端XML文档结构。 您应该扩展DefaultHandler并重写一些方法来实现xml解析。 覆盖的方法是 startDocument&#xff08;&#xff09;和endDocument&#xff08;&#xff09;–…

第一个Python程序

在E:\Python 下新建一个hello.py文件&#xff0c;里面的内容是print(hello world) 进入命令提示窗格&#xff0c;输入E: 点击回车 输入 cd python 点击回车 输入Python hello.py 结果如图 转载于:https://www.cnblogs.com/lgqboke/p/5882049.html

matlab导入txt生成曲面,求助:怎样将txt的数据导入到Matlab中并根据参数画出波形...

导师让我把波形画出来&#xff0c;这下完全不会啊&#xff01;希望各位高手帮帮在下……txt中部分数据如下&#xff1a;ID DDD HH:MM:SS.mmmuuun PARA1 PARA2 CH RISE COUN ENER DURATION AMP A-FRQ RMS ASL PCNTS THR R-FRQ I-FRQ SIG STRNGTH ABS-ENERGY1…

Java多线程:易失性变量,事前关联和内存一致性

什么是volatile变量&#xff1f; volatile是Java中的关键字。 您不能将其用作变量或方法名称。 期。 我们什么时候应该使用它&#xff1f; 哈哈&#xff0c;对不起&#xff0c;没办法。 当我们在多线程环境中与多个线程共享变量时&#xff0c;我们通常使用volatile关键字&…

20145219 《信息安全系统设计基础》第01周学习总结

20145219 《信息安全系统设计基础》第01周学习总结 教材学习内容总结 别出心裁的Linux命令学习法 1、Ubuntu快捷键 CTRLALTT:打开终端&#xff1b;CTRLSHIFTT&#xff1a;新建标签页&#xff1b;ALT数字N&#xff1a;终端中切换到第N个标签页&#xff1b;Tab:终端中命令补全&…

拉盖尔多项式 matlab,类氢原子的定态波函数

&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp预备知识 球坐标系中的定态薛定谔方程&#xff0c;原子单位制本文使用原子单位制&#xff0e;类氢原子(hydrogen-like atom)被定义为原子核有 $Z$ 个质子(核电荷为 $Ze$)有一个核外电子的原子/离子&#xff0…

再论EM算法的收敛性和K-Means的收敛性

标签&#xff08;空格分隔&#xff09;&#xff1a; 机器学习 &#xff08;最近被一波波的笔试面试淹没了&#xff0c;但是在有两次面试时被问到了同一个问题&#xff1a;K-Means算法的收敛性。在网上查阅了很多资料&#xff0c;并没有看到很清晰的解释&#xff0c;所以希望可以…

java xml dom getelementbyid,DOM中常见的元素获取方式

1.getElementById获取元素 返回的是一个元素对象var timer document.getElementById(time);console.dir 打印返回元素对象&#xff0c;更好的查看里面的属性和方法console.dir( timer );2.getElementsByTagName 获取某类标签元素 返回的是 获取过来元素对象的集合 以…

杰尔·地狱

什么是JAR地狱&#xff1f; &#xff08;或者是classpath地狱&#xff1f;还是依赖地狱&#xff1f;&#xff09;在考虑使用Maven或OSGi等现代开发工具时&#xff0c;哪些方面仍然有意义&#xff1f; 有趣的是&#xff0c;似乎没有对这些问题的结构化答案&#xff08;即&#…

matlab radsimp,[转载]MATLAB学习笔记(八)

符号运算符号运算分为以下几类&#xff1a;符号表达式和符号矩阵的操作整体定义为符号微积分符号线性方程符号微分方程A、符号变量、符号表达式和符号方程的分解一、 生成符号变量要使用sym和syms&#xff1a;使用sym函数可以定义符号表达式&#xff0c;此时有两种定义方法&…

windows,python3.x下安装pyspider

由于是初学者&#xff0c;业余学习&#xff0c;习惯使用windows&#xff0c;初次了解到pyspider写代码和调试代码非常简便&#xff1b;作者binux是在Ubuntu下部署测试的。在作者的博客看到windows下安装的讨论。windows直接安装失败主要是lxml、pycurl安装失败&#xff0c;需要…

matlab实验符号计算答案,实验五matlab符号计算

实验五matlab符号计算 实验 5 符号计算 教师评分班级 学号 姓名实验日期 2014 年 6 月 17 日 星期 二 第 1 至 2 节课实验地点实验目的1. 掌握定义符号对象的办法2. 掌握符号表达式的运算法则以及符号矩阵运算3. 掌握求符号函数极限及导数的方法4. 掌握求符号函数定积分和不定积…

junit4 单元测试框架_超越JUnit –测试框架的替代方案

junit4 单元测试框架JUnit是事实上的Java单元测试框架&#xff0c;但是可能有一些新的&#xff08;不是那么新的&#xff09;框架可以用于Web开发。 在采用之前可能要问自己的问题&#xff1a; 它们是否快速&#xff0c;容易开发并因此成本低廉&#xff1f; 他们运行快并因此鼓…

Java学习笔记之:Java String类

一、引言 字符串广泛应用在Java编程中&#xff0c;在Java中字符串属于对象&#xff0c;Java提供了String类来创建和操作字符串。 创建字符串最简单的方式如下: String str "Hello world!"; String类型是特殊的引用类型&#xff0c;我们也可以通过实例化的方式来创建 …

java循环输入直到,使用循环接受其他用户输入,直到用户输入结束输入的值

我是Java的新手 . 我需要一些帮助&#xff0c;使用循环接受其他用户输入&#xff0c;直到用户输入结束输入的值 . 我的问题从语句“System.out.println(”你完成了吗&#xff1f;输入大写的Y / N)开始 . 下面是我的代码 .公共类EmployeeData {//declare variablesprivate Strin…

WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载

昨天&#xff0c;WildFly团队发布了最新版本的WildFly 10 。 CR2很可能是预计于十月份发布最终版本之前的最后一个版本。 即使主要支持的Java EE规范是7&#xff0c;WildFly 8和WildFly 9仍具有许多新功能&#xff0c;该版本现在具有三个服务器版本&#xff0c;实现了Java EE 7…