Redis集群方案应该怎么做?

公司redis集群有了蛮大的规模,权且来分享下redis集群!首先,不可否认的是,redis的单机性能相当高,但是就算把内存大量扩大(垂直扩展),也不可能满足大业务需要的性能和可维护性!所以,集群是很好的一个选择,通过集群可以实现水平扩展,提升整体的性能!集群方案1:使用客户端分片的方式,增加多台redis服务器之后,在业务端使用某种路由规则(hash算法等),将不同key对应的数据放在不同的redis服务器中,实现内容分发!但是这样的方式有很多缺点,比如业务代码和redis数据路由代码严重耦合,可扩展性也十分底下,需要增加redis实例的同时,修改原先的分发规则,而一旦出现问题,排查难度大(因为运维和代码端都要查)!集群方案2:使用开源产品twemproxy作为redis代理!中间件twemcache负责接收业务端的请求,然后从不同的redis实例中收集数据传送给业务方,起到一个中间代理的作用!业务端像连接一个redis实例一样连接twemproxy,实现了业务代码和redis之间的解耦合!同时,对于失效的redis会被自动踢出,防止数据的丢失,不过twemproxy作为一个中间件,肯定会对需要实时性强的系统造成性能损失,动态无痕迹的增加redis实例也是很困难的!!集群方案3:使用codis集群,类似于twemproxy,客户端也不需要去连接redis实例,而使用codis作为中间件,让codis底层自己去获取数据,增加的codis dashboard可以对codis proxy和codis server进行统一管理,对实例节点的改变可以有效应对!集群方案4:redis自主集群,使用纯redis实现集群,完全的去中心化!redis集群把所有的key放在16384个slot中,各个redis可以通过重定向引导客户端访问数据所在的集群点,比如client访问redis2,redis2发现数据的key在redis1中,就引导客户端重定向去redis1中取数据,这样不需要别的中间件就能很好的实现数据获取,而且这样的纯redis方式,部署起来也是十分方便的!集群方案5:直接买阿里,腾讯的集群吧,想要啥样的给你啥样的。

在高可用集群中,如何解决脑裂问题?

什么是脑裂问题脑裂(brain-split):脑裂是指在主备切换时,由于切换不彻底或其他原因,导致客户端和Slave误以为出现两个active master,最终使得整个集群处于混乱状态。脑裂问题主要有哪些解决方式共享存储fencing:确保只有一个Master往共享存储中写数据。客户端fencing:确保只有一个Master可以响应客户端的请求。

Slave fencing:确保只有一个Master可以向Slave下发命令。 Hadoop的脑裂怎么解决Hadoop公共库中对外提供了两种fenching实现,分别是sshfence和shellfence(缺省实现),其中sshfence是指通过ssh登陆目标Master节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确),shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。

切换对外透明:为了保证整个切换是对外透明的,Hadoop应保证所有客户端和Slave能自动重定向到新的active master上,这通常是通过若干次尝试连接旧master不成功后,再重新尝试链接新master完成的,整个过程有一定延迟。在新版本的Hadoop RPC中,用户可自行设置RPC客户端尝试机制、尝试次数和尝试超时时间等参数。

双机热备中的脑裂在“双机热备”高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障,2个节点上的HA软件像“裂脑人”一样,“本能”地争抢“共享资源”、争起“应用服务”,就会发生严重后果:或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏(常见如数据库轮询着的联机日志出错)。

在系统中增加quartz定时任务集群,tomcat集群会多次执行,怎么解决呢?

做过类似的功能,不一定非得用分布式定时任务,还是要结合项目实际来选择具体的解决方案;从简单的说起,给大家介绍几个(不一定要选高大上的方案,适合最重要)。比如数据库中每天都会有一百万条数据待处理,一个定时任务(记为A)要处理完这一百万条数据,需要10个小时;如果想加快这个处理速度,我们首先能想到的是多部署一个批处理程序(记为B),这时候理论上需要10/2=5个小时,可以把任务都处理完。

方案一:待处理任务表增加一个处理标志的字段,例如0=待处理,1=处理中,2=处理完成;当A任务取到待处理数据的时候,将此字段更新成1,处理完之后更新成2;当字段=1/2的时候,B任务不会取到这条数据;但是这种方法的问题极大,因为很容易发生一条待处理任务在被A查询到,但是未更新处理状态前,就被B任务取到,这样就会造成重复处理的问题。

方案二:把处理任务进行人为的划分,A处理一批数据,B处理一批数据。可以从纯数据角度划分,比如id%2=0的A处理,id%2=1的B处理,也可以从业务角度划分,比如某个字段in(A,B,C)的A处理,某个字段in(X,Y,Z)的A处理;这样做不会造成数据重复处理,但是也有一些问题:数据不一定能够平均分配,比如字段in(A,B,C)的数据有90万条,字段in(X,Y,Z)的有10万条。

难以扩展,因为条件是写死的,所以如果要增加减少机器的话比较麻烦;如果其中一台机器挂掉,那么这部分数据就不会处理。方案三:方案一改进一下,增加分布式锁(可以是数据库、Redis、ZK),谁能抢到锁,谁才能提取待处理任务,并更新处理状态,比如一次提取一万行数据,并把这些数据的待处理状态更新成【处理中】,然后把锁释放掉,再由其他的节点抢锁。

这种方案需要考虑的东西也不少:要考虑锁超期的问题:如果A抢到锁,还没释放锁之前A就挂掉了,那么所有任务都会被卡主。如果锁超期被释放掉,A处理到一半的任务还需要被其他任务处理(失效转移)。可以和方案二结合,做任务分片,批处理程序抢到锁后,领取一个任务分片进行处理。方案四:直接采用分布式任务处理框架,我熟知的就是Elastic-Job了,它的功能更为强大,不过主要的功能嘛,你能理解前三个方案的话,这个方案也就容易理解了(基本上就是上面那些东西)。


文章TAG:我是曙光曙光明白再引关注  曙光集群系统中如何使用命令切换节点  我是  曙光  光明  
没有了