




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规则放入多个不同的服务器节点,来降低单节点服务器的压力。上一篇我们讲到了 Redis 的主从复制技术,当实现了多节点的 master-slave 后,我们也可以把它叫做集群,但我们今天要讲的集群主要是利用切片技术来组建的集群。集群要实现的目的是要将不同的 key 分散放置到不同的 redis 节点,这里我们需要一个规则或者算法,通常的做法是获取 key 的哈希值,然后根据节点数来求模,但这种做法有其明显的弊端,当我们需要增加或减少一个节点时,会造成大量的 key 无法命中,这种比例是相当高的,所以就有人提出了一致性哈希的概念。一致性哈希有四个重要特征:均衡性:也有人把它定义为平衡性,是指哈希的结果能够尽可能分布到所有的节点中去,这样可以有效的利用每个节点上的资源。单调性:对于单调性有很多翻译让我非常的不解,而我想要的是当节点数量变化时哈希的结果应尽可能的保护已分配的内容不会被重新分派到新的节点。分散性和负载:这两个其实是差不多的意思,就是要求一致性哈希算法对 key 哈希应尽可能的避免重复。但一致性哈希不是我们今天要介绍的重点,因为 Redis 引入另一种哈希槽(hash slot)的概念。Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。使用哈希槽的好处就在于可以方便的添加或移除节点。当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;内部机制,与我何干,对于我们来说,在新增或移除节点的时候不要让我们先停掉所有的 redis 服务我就谢天谢地了,这点它做到了。下面我们就开始动手搭建一个 redis 集群来体验一下。因为我们要启动多个 redis 实例,虽然我们可以直接通过命令行来启动,但始终是不怎么方便的,所以我们先来新建三个实例目录,分别是9001,9002,9003,目录名就是 redis 实例的端口号。我这里已经建好了目录,然后我们把以前编译过和修改过的 redis-server、redis.conf这两个文件分别拷贝到这三个目录里面,拷贝完之后就像这样子了:我们打开 redis.conf 文件,为了简单起见,我们只保留下面几个配置项:daemonize yesport 9001cluster-enabled yescluster-config-file nodes.confcluster-node-timeout 5000appendonly yes注意:port 要修改成对应目录的名字,也就是每个实例要有不同的端口。下面我们分别启动这三个实例:zhaoguihuadediannao: zhaogh$ cd applications/dev/redis-clusterzhaoguihuadediannao:redis-cluster zhaogh$ cd 9001zhaoguihuadediannao:9001 zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:9003 zhaogh$ cd ./9002zhaoguihuadediannao:9002 zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:9002 zhaogh$ cd ./9003zhaoguihuadediannao:9003 zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:9003 zhaogh$接下来我们来创建集群,让三个实例互相通讯:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb create -replicas 0 :9001 :9002 :9003 Creating clusterConnecting to node :9001: OKConnecting to node :9002: OKConnecting to node :9003: OK Performing hash slots allocation on 3 nodes.Using 3 masters::9001:9002:9003M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 :9001 slots:0-5460 (5461 slots) masterM: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b :9002 slots:5461-10922 (5462 slots) masterM: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 :9003 slots:10923-16383 (5461 slots) masterCan I set the above configuration? (type yes to accept): yes Nodes configuration updated Assign a different config epoch to each node Sending CLUSTER MEET messages to join the clusterWaiting for the cluster to join. Performing Cluster Check (using node :9001)M: 92c9912cb1ccf657c886ecd839dd32c66efd8762 :9001 slots:0-5460 (5461 slots) masterM: b6d46fcb8b0e6ee373b09a4f2cbcec744d1a259b :9002 slots:5461-10922 (5462 slots) masterM: 44ab30c7c589ffb15b9b04dd827c72cfaeedacb2 :9003 slots:10923-16383 (5461 slots) masterOK All nodes agree about slots configuration. Check for open slots. Check slots coverage.OK All 16384 slots covered.zhaoguihuadediannao:src zhaogh$需要注意的是执行redis-trib.rb 命令需要 ruby 的支持,如果你没有安装可以先到/gems/redis下载,然后离线安装。sudo gem install redis-3.0.7.gem -local下面我们用 redis 自带的客户端测试一下:zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001:9001 get testkey001- Redirected to slot 12786 located at :9003(nil):9003 set testkey002 testvalue002- Redirected to slot 401 located at :9001OK:9001 get testkey002testvalue002:9001 set testkey003 testvalue003OK:9001可以看到,虽然我们第一次连接的是9001端口,当我们去获取 testkey001 的时候,redis cluster 自动帮我们重定向到 9003 。当我们在 9003 设置 testkey002 时,redis cluster 又重定向到 9001 。总的来说, redis 集群部署起来还是非常方便的,遗憾的是,目前几乎还没有 c# 的客户端能很好的支持 redis 集群,真是非常的悲哀,我们期待他们的更新。下一遍中,我们继续讨论 redis 集群,比如,如何增加节点,移除节点,重新切片等,敬请期待。Redis 集群(中) 昨天晚上钓鱼回来,大发神经,写了篇概括程序员生活现状的文章,没想到招来众多人的口诛笔伐,大有上升到政治层面的趋势。我也许不会再发表任何冲击心灵的文章,我希望给大家带来更多的正能量,所以那篇文章已被我删除。我的本意只是想让各位看过文章之后能冷静地思考自己的程序人生,不管是对是错,人都有选择的权力,走好自己的路。我没有你们想象中那么悲观,我也在不懈的努力,哪怕一时的跌倒,我也要重新站起。生活无时无刻不是压力,让我们背起行囊,迈出踏实的一步,走起!我们继续我们的 redis 缓存之旅。前一篇我们实现了一个简单的 redis 集群,redis 也为了让我们方便的维护集群提供了非常好的工具。首先请大家参照我的上一篇文章,把集群环境搭建起来。OK,我用了分分钟的时间已经搭建好了。OK All 16384 slots covered.zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001:9001 get testkey001- Redirected to slot 12786 located at :9003(nil):9003如何增加节点:首先我们创建一个叫做 9004 的目录:zhaoguihuadediannao:redis-cluster zhaogh$ mkdir 9004zhaoguihuadediannao:redis-cluster zhaogh$接着我们将 9001 目录下的 redis-server 、 redis.conf 两个文件拷贝到 9004 目录:zhaoguihuadediannao:redis-cluster zhaogh$ cp 9001/redis-server 9004zhaoguihuadediannao:redis-cluster zhaogh$ cp 9001/redis.conf 9004然后我们打开 redis.conf 文件修改里面的端口配置项,将其改为 9004 。启动 9004 实例:zhaoguihuadediannao:redis-cluster zhaogh$ cd 9004zhaoguihuadediannao:9004 zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:9004 zhaogh$想要把这个实例加入到集群,我们只需要执行 redis-trib.rb 命令:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb add-node :9004 :9001第一个参数是我们刚才启动的新实例,第二个参数是集群中已有的节点。检查一下新节点是否已经加入:zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001:9001 cluster nodes0e8f980bfe7a682e3d71b15523a41293535b8ccd :0 myself,master - 0 0 1 connected 0-5460cbb01bdfdc265b190496956354d84aaae6e7d54d :9004 master - 0 1401952316346 0 connected708e6e14474e3a99677b05ff89bd857375884437 :9002 master - 0 1401952314325 2 connected 5461-10922a7f9d3c64540cc3fc8cd3072e573bb8ab0bf1e6f :9003 master - 0 1401952315334 3 connected 10923-16383:9001我们可以发现 9004 并不包含任何哈希槽,因为它还没有数据。我们还可以为集群中的主节点增加从节点用于只读查询。如何增加从节点:我们还是要创建目录,拷贝那两个文件,修改配置,然后启动实例:zhaoguihuadediannao:redis-cluster zhaogh$ mkdir 9005zhaoguihuadediannao:redis-cluster zhaogh$ cp 9001/redis-server 9005zhaoguihuadediannao:redis-cluster zhaogh$ cp 9001/redis.conf 9005修改 port 为 9005zhaoguihuadediannao:redis-cluster zhaogh$ cd 9005zhaoguihuadediannao:9005 zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:9005 zhaogh$执行下面的命令,增加从节点:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb add-node -slave :9005 :9001第一个参数为从节点,第二个参数为主节点。如何删除一个节点:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb del-node :9001 cbb01bdfdc265b190496956354d84aaae6e7d54d这里要注意一下,第一个参数是集群中的任何一个主节点地址,而第二个参数是要删除节点的 ID,这个ID如果你不知道的话,可以通过 cluster nodes 命令查看。还有一点就是要删除的节点必须是空的,也就是不能缓存任何数据,否则会删除不成功。对于非空节点,在删除之前需要重新分片,将缓存的数据转移到别的节点。如何重新分片:我们先给某个节点做点数据:zhaoguihuadediannao:src zhaogh$ ./redis-cli -c -p 9001:9001 set testkey001 testvalue001- Redirected to slot 12786 located at :9003OK:9003现在 9003 上已经有数据了,我们尝试删除一下:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb del-node :9001 78ec1fd6647b79627d7c29bb2b22d04a4a6c43b3 Removing node 78ec1fd6647b79627d7c29bb2b22d04a4a6c43b3 from cluster :9001Connecting to node :9001: OKConnecting to node :9002: OKConnecting to node :9003: OKERR Node :9003 is not empty! Reshard data away and try again.zhaoguihuadediannao:src zhaogh$没有删除成功,我们来重新分片,把 9003 上的数据转移:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb reshard :9003然后输出了很多信息,很多数值和ID都可以从这段信息中找到。How many slots do you want to move (from 1 to 16384)? 5461会问你要移动多少个哈希槽,我们把 9003 上的所有哈希槽都移走,5461 这个数字可以从终端上看到,或许你的实际情况不是这个数字。What is the receiving node ID? 4d2e0a8360795ce7ce8381c68746034aeba3c9b9然后问你你要把这些哈希槽移到哪儿去,我指定了 9001 的 节点 ID。Please enter all the source node IDs. Type all to use all the nodes as source nodes for the hash slots. Type done once you entered all the source nodes IDs.Source node #1:78ec1fd6647b79627d7c29bb2b22d04a4a6c43b3Source node #2:done之后,redis 列出了重新分片计划,最后问你Do you want to proceed with the proposed reshard plan (yes/no)? yes执行完成后,我们看看 9003 上还有没有 key:zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 9003:9003 keys *(empty list or set):9003再看看 9001 上是不是有这个 key 了zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 9001:9001 keys *1) testkey001:9001没错,果然转移过来了。最后我们试试能不能把 9003 删除:zhaoguihuadediannao:src zhaogh$ ./redis-trib.rb del-node :9001 78ec1fd6647b79627d7c29bb2b22d04a4a6c43b3 Removing node 78ec1fd6647b79627d7c29bb2b22d04a4a6c43b3 from cluster :9001Connecting to node :9001: OKConnecting to node :9002: OKConnecting to node :9003: OK Sending CLUSTER FORGET messages to the cluster. SHUTDOWN the node.zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 9003Could not connect to Redis at :9003: Connection refusednot connected非常好,its very good.Redis 主从复制 Redis 的主从复制配置非常容易,但我们先来了解一下它的一些特性。1. redis 使用异步复制。从 redis 2.8 开始,slave 也会周期性的告诉 master 现在的数据量。可能只是个机制,用途应该不大。2. 一个 master 可以拥有多个 slave,废话,这也是业界的标配吧。3. slave 可以接收来自其他 slave 的连接。意思是不是就是说 slave 在接收其他的slave的连接之后成为 master ?等下我们来验证。4. redis 复制在 master 这一端是非阻塞的,也就是说在和 slave 同步数据的时候,master 仍然可以执行客户端的操作命令而不受其影响。这点都不能保证,要你干嘛?5. redis 复制在 slave 这一端也是非阻塞的。在配置文件里面有 slave-serve-stale-data 这一项,如果它为 yes ,slave 在执行同步时,它可以使用老版本的数据来处理查询请求,如果是 no ,slave 将返回一个错误。在完成同步后,slave 需要删除老数据,加载新数据,在这个阶段,slave 会阻止连接进来。6. Replication can be used both for scalability, in order to have multiple slaves for read-only queries (for example, heavySORToperations can be offloaded to slaves), or simply for data redundancy.这句话我也没理解什么意思。7. 使用复制可以避免 master 因为需要把全部的数据集写入磁盘而造成的开销,因此可以把 master 中 save 配置项全部注释掉,不让它进行保存,然后配置 slave ,让 slave 保存。虽然有这个特性,但是我们好像一般不这么做。好吧,我们做几个例子练习一下。先打开三个终端,然后起三个实例,分别用三个 client 去连接它们:zhaoguihuadediannao:src zhaogh$ ./redis-server -port 10000 -daemonize yeszhaoguihuadediannao:src zhaogh$zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 10000端口10000的做 master。slave 01:zhaoguihuadediannao:src zhaogh$ ./redis-server -port 10001 -daemonize yeszhaoguihuadediannao:src zhaogh$zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 10001slave 02:zhaoguihuadediannao:src zhaogh$ ./redis-server -port 10002 -daemonize yeszhaoguihuadediannao:src zhaogh$zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 10002上面只是让它们的实例启动了并用客户端去连接它,并没有设置主从关系。在 slave 01 和 slave 02 上执行下面的命令::10001 slaveof 10000OK:10001这样就设置好了主从关系。我们来试试有没有效果。:10001 get testkey001(nil):10001这个时候是没有值的。master 上执行::10000 set testkey001 testvalue001OK:10000然后看看 slave 上有没有::10001 get testkey001testvalue001:10001:10002 get testkey001testvalue001:10002有了,是不是比*点读机还 easy ?已经有了感性的认识,我们来介绍一下它的原理吧。当你设置了主从关系后,slave 在第一次连接或者重新连接 master 时,slave 都会发送一条同步指令给 master ;master 接到指令后,开始启动后台保存进程保存数据,接着收集所有的数据修改指令。后台保存完了,master 就把这份数据发送给 slave,slave 先把数据保存到磁盘,然后把它加载到内存中,master 接着就把收集的数据修改指令一行一行的发给 slave,slave 接收到之后重新执行该指令,这样就实现了数据同步。slave 在与 master 失去联系后,自动的重新连接。如果 master 收到了多个 slave 的同步请求,它会执行单个后台保存来为所有的 slave 服务。一旦 master 和 slave 在失去联系并重新连接上,总是会重新进行一次完整的同步。不过从 redis 2.8 开始,只是部分重新同步也是可以的。具体请大家参考官方文档。祝大家端午节快乐。Redis 的配置 我们说Redis是一个强大的Key-Value存储系统,在前面我们已遇到了两个问题:1、redis server 启动后,独占进程,能不能修改为后台服务呢?2、redis server 服务是单线程的,而我的机器是多核的,能不能在同一台机器上开启多个实例更充分的利用 cpu 资源呢?但6379端口已经被前一个实例绑定,肯定会有冲突,那能不能修改默认端口呢?答案是肯定的,redis 提供了灵活的配置方式,一种可以通过配置文件来配置,另一种你可以在运行时通过 config set 命令来修改配置。我们先来看看配置文件吧。殊不知我们在前面启动 server 的时候敲的 ./redis-server 命令,如果后面不附加参数,它是按默认配置来启动 redis 服务的,其实它后面还可以附加一个配置文件路径的参数。这个配置文件在哪?在redis根目录下有一个redis.conf文件,这个文件为了提供了默认的配置和示例。你不要轻易去动这个文件,除非你非常牛逼。我们还是保险起见先复制一个副本吧。打开副本我们发现这个文件真的好大好长啊,全是英文看得我也难受啊,也不见哪座大神帮忙翻译一下,给个现成的中文版,太自私了吧,哥今天一晚不睡也要给你们一个交代。太长了,翻译了一个晚上才搞了一部分出来,不过主要的配置项都翻译出来了,我后面有时间继续翻译。看这里。记得顺便去关注一下我的 restful.data 。把这个文件下载下来后,拷贝到 src 目录下面,也就是和 redis-server 在同一个目录,方便我们操作。我们稍微改一下配置,看看能不能把我们前面提到的两个问题解决了。首先我们修改daemonize 配置项,把它设置为 yes,打开终端,我们执行一下 redis-server 命令。zhaoguihuadediannao: zhaogh$ cd applications/dev/redis/srczhaoguihuadediannao:src zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:src zhaogh$ ./redis-cli:6379是不是已经不再独占进程了,启动守护进程后,我们仍然可以执行 redis-cli 命令。先停掉 redis 服务::6379 shutdown:6379 quitzhaoguihuadediannao:src zhaogh$然后我们修改 port 配置项为 6378,然后再启动服务:zhaoguihuadediannao:src zhaogh$ ./redis-server ./redis.confzhaoguihuadediannao:src zhaogh$ ./redis-cliCould not connect to Redis at :6379: Connection refusednot connected因为我们修改了默认端口号,已经连不上去了,尝试加上端口参数。zhaoguihuadediannao:src zhaogh$ ./redis-cli -p 6378:6378成功了连上了。篇幅有限,redis.confi 中其他配置项请大家结合注释去深入的了解。下面介绍另外一种配置方式,通过命令行来配置。假如说我们不想修改配置文件来启动指定端口号的redis服务,我们可以在终端上执行下面的命令:zhaoguihuadediannao:src zhaogh$ ./redis-server -port 6379 -daemonize yeszhaoguihuadediannao:src zhaogh$ ./redis-cli -p 6379:6379但我还是推荐使用配置文件的方式。如果在生产环境里面需要修改某些配置项,但我们又不想停掉服务,怎么办?Redis允许在运行的过程中,在不重启服务器的情况下更改服务器配置,同时也支持 使用特殊的CONFIG SET和CONFIG GET命令用编程方式查询并设置配置。:6379 config get port1) port2) 6379:6379:6379 config set port 6380(error) ERR Unsupported CONFIG parameter: port:6379我试图直接修改端口号,没有成功,我是有点想当然了,因为一旦修改端口必然需要重启服务,重新绑定端口,所以并不是所有的配置项都能在运行时进行修改。那我们来修改一个允许修改的配置项。:6379 config set tcp-keepalive 60OK:6379上面的例子,我把心跳包发送时间间隔修改成了60秒。你们可以自己尝试着去修改其他配置项。技术上有很多事情不是靠看几篇文章,通过道听途说就能明白的,想要真正弄清楚,必须要自己亲自去尝试,实践才是检验真理的唯一标准,就像很多朋友给我推荐车一样,说这车好,那车差,其实自己都没开过,我发现很多程序员嘴上都说的一套一套的,实际做起事来真不行,这样的人适合做销售,会忽悠,当然这也是种能力。Redis的安装与使用 一、什么 RedisREmoteDIctionaryServer,简称 Redis,是一个类似于Memcached的Key-Value存储系统。相比Memcached,它支持更丰富的数据结构,包括string(字符串)、list(链表)、set(集合)、zset(sorted set -有序集合)和hash(哈希类型),并提供了数据持久化机制,在某些场景下,你完全可以把它当做非关系型数据库来使用。它是一个高性能的存储系统,能支持超过 100K+ 每秒的读写频率。同时还支持消息的发布/订阅,从而让你在构建高性能消息队列系统时多了另一种选择。二
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 兼职合同范本15篇模板
- 集团采购礼宾车合同范本
- 百万便利店转让合同范本
- 北京市劳务派遣合同范本
- 水沟修筑外包合同协议书
- 护士企业编制面试题库含完整答案详解(考点梳理)
- 2026届贵州省罗甸县第一中学化学高一上期中综合测试试题含解析
- 浙江省杭十四中2026届高二化学第一学期期末考试试题含答案
- 陕西师范大学附中2026届高一化学第一学期期中达标检测模拟试题含解析
- 2026届山东省泰安第四中学高一化学第一学期期中复习检测试题含解析
- 伤口造口新进展课件
- 中职统计基础知识课件
- 预防校园欺凌-共创和谐校园-模拟法庭剧本
- 《人间词话》十则公开课
- 磁刺激仪技术参数
- Q∕GDW 11311-2021 气体绝缘金属封闭开关设备特高频法局部放电在线监测装置技术规范
- 通用机场建设审批程序
- 城市雕塑工程工程量清单计价定额
- 道路保通专项方案
- ansys的讲义ANSYS有限元分析培训
- 120#溶剂油安全技术说明书(共4页)
评论
0/150
提交评论