当前位置: 首页 > news >正文

源代码网站开发设计师必备的国际设计网站

源代码网站开发,设计师必备的国际设计网站,wordpress显示分页,seo赚钱目录 1、为什么引入集群 1.1、先来了解集群是什么 1.2、哨兵模式的缺陷 引入集群解决了什么问题 1.3、使用集群#xff0c;如何存储数据 2、三种主流的分片方式【经典面试题】 2.1、哈希求余算法 2.1.1、哈希求余算法的介绍 2.1.2、哈希求余算法如何扩容 2.2、一致性…目录 1、为什么引入集群 1.1、先来了解集群是什么 1.2、哨兵模式的缺陷  引入集群解决了什么问题 1.3、使用集群如何存储数据 2、三种主流的分片方式【经典面试题】 2.1、哈希求余算法  2.1.1、哈希求余算法的介绍  2.1.2、哈希求余算法如何扩容 2.2、一致性哈希算法 2.2.1、一致性哈希的流程 2.2.1、一致性哈希算法中如何扩容 2.3、哈希槽分区算法 2.3.1、哈希槽分区算法介绍 2.3.2、哈希槽分区算法相关问题说明 3、Redis采用哪种分片方式 4、搭建集群环境基于docker  4.1、创建目录 4.2、使用.sh脚本批量生成配置文件 4.3、编写docker-compose.yml文件 4.4、启动容器 4.5、构建集群 5、使用集群 6、故障处理-主节点挂了 6.1、故障判定 6.2、故障迁移 6.3、集群宕机 7、集群扩容 第一步把新的主节点加入到集群 第二步重新分配slots 第三步给新的主节点添加从节点 8、删除主节点 1、为什么引入集群 1.1、先来了解集群是什么 广义上来说只要是多个机器构成了一个分布式系统都可以称为是一个“集群”狭义上来说Redis提供的集群模式这个集群模式之下这要是解决存储空间不足而需要拓展存储空间的问题 举例来说我们前面提到过的主从复制和哨兵模式就属于是“广义上的集群”Redis中的集群模式叫做狭义上的集群也就是我们本篇文章要介绍的集群~ 1.2、哨兵模式的缺陷  引入集群解决了什么问题 哨兵 主从复制只能提高可用性而不能提高数据的存储容量当我们需要存的数据接近或超过机器的物理内存时就需要引入更多的机器来存储数据。 这种情况下对数据的管理只是使用哨兵和主从复制就难以胜任引入集群后不论是数据管理也好还是后续存储空间需要扩容都会更加友好的处理~ 总结一句话引入集群就是解决了扩容问题~ 1.3、使用集群如何存储数据 假设有1TB的数据需要存储我们此时使用集群的方式存储例如分为三台机器来存储如图 但实际上是不止这么几台机器的还有从节点呢~ 上述中每个篮框部分就是一个分片Sharding当需要更多的存储空间时增加更多的分片即可~ 那么在这里又会引入一个新的问题把数据分成多份怎么分 下面介绍了三种主流的分片方式~ 2、三种主流的分片方式【经典面试题】 2.1、哈希求余算法  2.1.1、哈希求余算法的介绍  小伙伴们肯定多少对哈希表的基本思想会有一点了解的我就不具体解释了~         在这里的分片方式中简单来说就是借助一个哈希函数把key映射到整数再针对数组的长度求余就可以得到一个数组下标啦~ 说明一把key映射到整数 因为求余中当然是要求该数为整数而key值不一定为整数所以我们借助映射来得到每个不同的key所对应的整数。例如使用md5就可以将一个字符串经过一系列的数学变换将其转换为一个整数【十六进制并且计算出的所有字符串的长度都是固定的结算出的结果比较分散两个高度相似的字符串计算出的结果差异会很大计算结果是不可逆的】 说明二针对数组长度求余分片方式中数组长度怎么确定 我们使用上述得到的整数模上一个分片数量。这里其实就是把分片的数量作为是数组长度~ 例如我们这里有三个分片编号为 0、1、2 结合上图也就是假设有几个key被转换为整数后为0 1 2 3 4 5 6 7 8 9 10 11给这些整数模3在就可以把对应key的数据存储进去 ~ 在进行查询时也是一样的步骤先把key转换为整数然后求余再去对应的机器中查找~ 2.1.2、哈希求余算法如何扩容 具体如何扩容我们结合上面的例子来说上面说假设有3个分片来存储那我们再假设这个三个分片存储数据不够了要进行扩容需要我们再增加一个分片~ 此时增加分片后我们需要对数据整理也就是说原本的数组长度为3此时变成了4原本储存的那一大批数据就需要拿出来重新存进去如图 我们能看到原本的12个数据再次整理后只有三个【图中标红了】还在原本的分片中按照不精确的数学统计来说需要重新搬运的数据高达百分之七十五以上~  而且根据上图我们能看到这里扩容时是通过“替换”的方式来实现搬运数据时需要单独先拿四台机器搬运搬运完后原本的三台机器才可以拿走到其他地方使用相当于要同时使用七台机器这还只是说主节点的机器呢 总结哈希求余算法虽然实现相对简单但是在扩容时依赖的机器较多成本高操作步骤也非常复杂~ 2.2、一致性哈希算法 一致性哈希最初提出来就是为了解决上述哈希求余的缺点的降低了扩容时搬运数据的开销更加高效的进行扩容~ 在哈希求余算法中各个数据是交替出现也就是说整数 0 1 2这样的连续数据的存储位置是分别在三台不同的分片机器上的而一致性哈希则会将其放置在同一个分片上~ 2.2.1、一致性哈希的流程 步骤一将0~2^32-1这个数据空间映射到一个圆环上。数据按照顺时针方向增长~ 图示 步骤二把分片放到圆环的某个位置上 图示  步骤三 此时有一个key计算得到hash值整数为H此时就顺着这个H所在的位置顺时针往下找找到的第一个分片就是这个key所从属的分片~ 图示 相当于是N个分片的位置把整个圆环分成了N个管辖区间key的hash值落在哪个区间就归对应区间管理~  2.2.1、一致性哈希算法中如何扩容 扩容结合下图来看 我们可以看到新增的分片放置在0号和2号分片中间再进行数据搬运时只需要将0号分片上一半的数据搬运到新增的3号分片上。 这种搬运方式带来的好处 搬运的成本变低需要搬运的数量相对来说较少了 这种搬运方式的缺点数据分布不均匀 这个缺点有一种解决方案就是每次扩容多搞几个分片。这个方案虽然可行但是又会带来新的缺点可能会导致很多分片上数据并不多不仅需要的机器多而且这些机器的内存空间利用率不一定高就会造成浪费  2.3、哈希槽分区算法 为了解决搬运成本高和数据分布不均匀的问题提出了哈希槽算法~ 2.3.1、哈希槽分区算法介绍 首先准备16384个槽位然后根据下列算法公式放置key值。公式hash_slot crc16(key) % 16384 公式说明 crc16也是一种hash算法和md5类似计算后的值为整数~16384个槽位也就是[0,16383]并不是说每个槽位占据一个分片而是把这些槽位均匀的分配给现有的分片每个分片都需要记录自己当前有哪些槽位号~ 2.3.2、哈希槽分区算法相关问题说明 问题一分片如何分配的槽位 这个分配是很灵活的不一定要求每个分片持有的的槽位必须连续~ 例如分配1: 0号分片[0,5461]共5462个槽位1号分片[5462,10923]共5462个槽位2号分片[10924,16383]共5460个槽位 例如分配2 0号分片[0,4461] [13385,14385]1号分片[4462,81923] [14386,15386]2号分片[1923,13384] [15387,16383] 这里采用的相对平均比较的而不是严格的均匀~ 不管在实际情况中是如何分配的只要每个分片知道自己是持有哪些槽位即可~  问题二分片如何记录自己当前有哪些槽位号 每个分片都是使用“位图”的数据结构来表示出当前有多少槽位号~ 也就是说16384个bit位用每一位0/1来区分自己这个分片当前是否持有该槽位号~ 问题三新增分片时如何处理的 新增时可根据实际情况灵活调整Redis中当前某个分片包含哪些槽位是可以手动配置的下面只是一个举例 原本 0号分片[0,5461]共5462个槽位1号分片[5462,10923]共5462个槽位2号分片[10924,16383]共5460个槽位 新增后 0号分片[0,4095]共4096个槽位1号分片[5462,9557]共4096个槽位2号分片[10924,15019]共4096个槽位3号分片[4096,5461] [9558,10923] [15019,16383]共4096个槽位 问题四Redis集群是最多有16384个分片吗 并非是Redis集群是最多有16384个分片。如果是这样的话有16384个分片一个分片持有一个槽位那这对于集群的数据均匀是很难保证的可能有的分片上有多个数据有的分片上一个数据也没有并且这么大规模的集群本身的复杂度就会很高不可避免的会导致出故障的概率就会越大~ 问题五为什么是16384个槽位 原因一节点之间通过心跳包通信心跳包中包含了该节点持有哪些slots槽位这个是使用位图来表示的表示1638416k个slots需要的位图大小为2kb。如果说给定的槽位数更多了此时就需要消耗更多的空间例如可能需要8kb位图来表示。虽然8kb也没多大但是在频繁的网络心跳包中还是一个不小的开销~Redis集群一般建议不超过1000个分片Redis官方的建议~ 所以16k对于最大1000个分片来说是足够用的同时也会使对应的槽位配置位图体积不至于很大~ 3、Redis采用哪种分片方式 Redis采用的是分片方式3 —— 哈希槽分区算法~ 4、搭建集群环境基于docker  我们基于docker来搭建一个集群每个节点都是一个容器具体搭建出来的拓扑结构如下 接下来我们先准备9个节点来掩饰集群的搭建【下面我们会顺便多准备2个节点后续集群的扩容会用到~】  4.1、创建目录 看过上一篇的小伙伴会知道我们有一个Redis目录没有的小伙伴随便创建一个就好啦~ 我们进到这个Redis目录中先创建一个redis-cluster目录然后再创建两个文件 红框以外的目录是上一篇用到的没有的小伙伴不管了~ 4.2、使用.sh脚本批量生成配置文件 在Linux上以.sh后缀结尾的文件称为“脚本”【不理解脚本是什么意思的小伙伴可以理解他为一个“剧本”他里面就是把一些命令放到一个文件里让他们批量化执行。我个人感觉就是更加压榨计算机放松双手~】  将下面的内容复制到generate.sh文件中 for port in $(seq 1 9); \ do \ mkdir -p redis${port}/ touch redis${port}/redis.conf cat EOF redis${port}/redis.conf port 6379 bind 0.0.0.0 protected-mode no appendonly yes cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.30.0.10${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 EOF done#上下ip那里有些许差异for port in $(seq 10 11); \ do \ mkdir -p redis${port}/ touch redis${port}/redis.conf cat EOF redis${port}/redis.conf port 6379 bind 0.0.0.0 protected-mode no appendonly yes cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.30.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 EOF done说明下图可能标注有点乱根据我每句话前面标的序号顺序来看会好一些~ 复制进去成功后保存退出执行命令sh generate.sh  --或bash generate.sh 我们可以来查看目录 其中每个redis1/2/3/...节点中的配置文件redis.conf中的内容出ip外都是相同的例redis1 4.3、编写docker-compose.yml文件 将以下内容复制进刚才创建的文件docker-compose.yml中 version: 3.3 networks:mynet:ipam:config:- subnet: 172.30.0.0/24 services:redis1:image: redis:5.0.9container_name: redis1restart: alwaysvolumes:- ./redis1/:/etc/redis/ports:- 6371:6379- 16371:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.101redis2:image: redis:5.0.9container_name: redis2restart: alwaysvolumes:- ./redis2/:/etc/redis/ports:- 6372:6379- 16372:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.102redis3:image: redis:5.0.9container_name: redis3restart: alwaysvolumes:- ./redis3/:/etc/redis/ports:- 6373:6379- 16373:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.103redis4:image: redis:5.0.9container_name: redis4restart: alwaysvolumes:- ./redis4/:/etc/redis/ports:- 6374:6379- 16374:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.104redis5:image: redis:5.0.9container_name: redis5restart: alwaysvolumes:- ./redis5/:/etc/redis/ports:- 6375:6379- 16375:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.105redis6:image: redis:5.0.9container_name: redis6restart: alwaysvolumes:- ./redis6/:/etc/redis/ports:- 6376:6379- 16376:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.106redis7:image: redis:5.0.9container_name: redis7restart: alwaysvolumes:- ./redis7/:/etc/redis/ports:- 6377:6379- 16377:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.107redis8:image: redis:5.0.9container_name: redis8restart: alwaysvolumes:- ./redis8/:/etc/redis/ports:- 6378:6379- 16378:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.108redis9:image: redis:5.0.9container_name: redis9restart: alwaysvolumes:- ./redis9/:/etc/redis/ports:- 6379:6379- 16379:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.109redis10:image: redis:5.0.9container_name: redis10restart: alwaysvolumes:- ./redis10/:/etc/redis/ports:- 6380:6379- 16380:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.110redis11:image: redis:5.0.9container_name: redis11restart: alwaysvolumes:- ./redis11/:/etc/redis/ports:- 6381:6379- 16381:16379command:redis-server /etc/redis/redis.confnetworks:mynet:ipv4_address: 172.30.0.111 4.4、启动容器 命令docker-compose up -d 【如果自己的服务器太小的话执行这一步服务器可能会崩掉大家谨慎哈~】 由于我的服务器太拉的原因我就部署不了这么多节点了我把从节点去掉了三个相当于以前是每一个主节点有两个从节点现在只有一个从节点了~ 启动完毕 4.5、构建集群 按照我们预想的是前9个主机构建成集群3主6从。而我现在实际是3主3从~ 构建命令如下 redis-cli --cluster create 172.30.0.101:6379 172.30.0.102:6379 172.30.0.103:6379 172.30.0.104:6379 172.30.0.106:6379 172.30.0.108:6379 --cluster-replicas 1 --cluster create表⽰建⽴集群. 后⾯填写每个节点的 ip 和地址确保这个命令的 IP 和实际环境一致.--cluster-replicas 1 表⽰每个主节点需要两个从节点备份.  这个配置设置了以后redis 就知道 2个节点是一伙的一个分片上的一共 6 个节点一共是 3 个分片.   构建集群  构建成功 5、使用集群 任意连接一个节点下面是使用不同方式连接上同一个节点172.30.0.103:6379 说明 可以通过-h 连接也可以通过-p连接使用-p直接到对外端口 查看信息 注意点 当我们在启动时使用 -c 选项此时redis客户端会根据当前key计算出的槽位号自动匹配分片的主机进一步完成操作~ 如下 6、故障处理-主节点挂了 6.1、故障判定 判定步骤 节点A给节点B发送ping包B就会给A返回一个pong包。心跳包的ping和pong除了message type 属性之外其他部分都是一样的例如会包含集群的配置信息给节点的id该节点从属于哪个分片是主节点还从节点从属于于谁持有哪些slots的位图...。每个节点每秒钟都会给一些随机的节点发起ping包而不是全发一遍这样的设定是为了避免在节点很多的时候心跳包也很多例如9个节点如果全发就是72组心跳包随机发起一个就只用发9组心跳包当节点A给节点B发送器ping包B不能如期回应时A就会尝试重置和B的tcp连接看是否可以连接成功。如果仍然连接失败A就会把B设为PFAIL状态主观下线A判定B为Pfail后会通过Redis内置的Gossip协议和其他节点进行沟通向其他节点确认B的状态每个节点都会维护一个自己的“下线列表”由于视角不同每个节点的下线列表也不一定相同此时A发现其他很多节点也认为B为Pfail并且数目超过集群总个数的一半那么A就会把B标记成fail客观下线。并且会把这个消息同步给其他节点其他节点收到之后也会把B标记为fail至此B就彻底被判定为故障节点了~ 例如我们现在手动将redis1停了 连接上redis2观察结果 并且后续redis1如果恢复了重启了他依然是从节点因为主节点已经有了他挂的时候他的从节点就已经顶上了~ 6.2、故障迁移 迁移流程 从节点判定自己是否具有参选资格。如果从节点和主节点已经太久没通信会认为从节点的数据和主节点的差异太大时间超过阈值就是失去竞选资格具有竞选资格的节点比如C和D就会先休眠一定时间.【休眠时间 500ms基础时间 [0,500ms]随机时间 排名*1000ms】offset的值越大则排名越靠前比如C的休眠时间到了C就会给其他所有集群中的节点进行拉票操作。但是只有主节点才有投票资格主节点就会把自己的票投给C当C收到的票数超过主节点数目的一半时C就会晋升为主节点C执行slaveof no one并且让D执行slaveof C同时C还会把自己成为主节点的消息同步给其他集群的节点。其他节点也会随之更新自己保存的集群结构 上述这种算法叫做Raft算法是一种在分布式系统中广泛使用的算计.【在随机休眠时间的加持下基本上就是谁先唤醒谁就能成功竞选】 6.3、集群宕机 以下三种情况会出现集群宕机 某个分片所有的节点全部挂了某个分片主节点挂了但是没有从节点超过半数的主节点都挂了 7、集群扩容 扩容原因存储空间不够了呗。下面的扩容最终结果就是增加了一个主节点redis10并且redis11作为redis10的从节点~ 由于我的服务器带不起来那么多节点所以我就直接把redis6、redis8停了再演示扩容操作 步骤流程 第一步把新的主节点加入到集群 命令 redis-cli --cluster add-node 172.30.0.110:6379 172.30.0.101:6379 说明 add-node第一个ip和端口号表示新增的节点是什么第二个ip和端口号表示集群上的任意一个节点随便是谁都行主要是说明要加入的是哪个集群  可以看到新增的节点还没有分配slots: 第二步重新分配slots 命令 redis-cli --cluster reshard 172.30.0.101:6379 输入命令后会先打印出当前每个集群机器的情况然后要求用户输入要切分多少个slots  如果前面三个主节点每一个都给这个新节点匀一部分slots那么我们用16384/4即可在这里填入4096 输入后又问让哪个节点接收填写id我们直接粘贴redis10主机的id就可以了 接着又会让你选择从哪些节点且分出多少 all  表示所有的主节点或者手动指定某个以done结尾 这里我们输入all 输入all后并不会真正的搬运而是给出搬运的计划下面会等待你输入yes后才开始真正搬运搬运时不仅仅是slots重新划分也会把slots上对应的数据也进行搬运到新的节点主机上~【重量级操作】  第三步给新的主节点添加从节点 命令 redis-cli --cluster add-node 172.30.0.111:6379 172.30.0.101:6379 --cluster-slave 说明第一个ip和端口号表示新增的节点是什么第二个ip和端口号表示集群上的某一个主节点后面跟上--cluster-slaveof表示加入后作为这个主节点的从节点存储~ 8、删除主节点 命令 redis-cli --cluster del-node 172.30.0.101:6379 节点id 第一个ip和端口号表示所在集群是哪个~ 好啦本期就到这里咯下期见~~~
http://www.pierceye.com/news/862148/

相关文章:

  • 太原做手机网站临沂外贸网站
  • 哪个域名注册网站好下载爱南宁乘车
  • 网站备案接入商是什么交互设计个人网站
  • 移动 网站模板app推广视频
  • 网站网页设计中怎么添加页码信息wordpress中文包
  • 网站优化排名软件网怎么看网站服务器地址
  • iis网站建设中怎么免费做网站不要域名
  • 广州 网站开发 公司怎样做一个公众号
  • 注册网站域名需要什么河南网站建设定制
  • 白种女人做爰网站网站建设新闻动态
  • 360百度网站怎么做徐州企业建站模板
  • 宁波做公司网站的公司wordpress 说说 插件
  • 做毕业设计网站教程网页设计培训机构多少钱
  • 展览馆网站建设方案书wordpress 搬家 sae
  • 网站建设服务开税率多少的票重庆公积金门户网站
  • 网站推广的策略有哪些免费创建个人网站申请
  • 网站建设合同制苏中建设集团网站
  • 如何用织梦程序制作多个页面网站免费域名解析网站建设
  • 安徽省建筑人员信息网广州百度seo优化排名
  • 北海网站建设培训机构专业
  • 江苏艺居建设有限公司网站企业营销网站开发建设专家
  • 莱芜网站优化排名西安工程建设工程信息网
  • 二手网站建设的策划php做网站都需要学什么软件
  • 作品集的个人网站怎么做抖音代运营怎么样呢
  • 电子商务网页设计与网站建设论文在线设计培训
  • 做旅游网站的项目背景软件开发手册
  • 宁波品牌网站设计app外包接活
  • 清远市住房和城乡建设局门户网站图片软件制作工具
  • 宝马itms做课网站网站开发群
  • 网站开发工作协议书范本谷歌优化软件