mageek 发布的文章

实现高可用的两种方案与实战


我之前在一片文章 用Nginx+Redis实现session共享的均衡负载 中做了一个负载均衡的实验,其主要架构如下:

round.png

debian1作为调度服务器承担请求分发的任务,即用户访问的是debian1,然后debain1把请求按照一定的策略发送给应用服务器:debian2或者debain3,甚至更多的debain4、5、6......

状态数据可以放在外部的分布式缓存服务分布式数据库服务中,这样应用服务本身就是无状态的,所以机器增减都是很容易的,应用的高可用是有保证的(对于有状态的高可用不仅要注意机器增减与切换、还要注意备份冗余数据一致性等问题)。但是当时忽略了一个地方,那就是调度服务器debian1本身的高可用性没有考虑到,存在单点问题。

高可用的首要想法就是双机热备,故障时自动切换,所以我们要给debian1加一个备机debain1'。我现在按照自己的知识粗浅的把解决方案分为两类:客户端有感知的高可用对客户端透明的高可用,并分别挑选一个示例做一下实验。

注:下面实现高可用都用的是双机热备,为了方便,把调度服务器debian1简称为主机,把调度服务器debian1的备机debian1'简称为备机


基于一致性哈希的分布式内存键值存储——CHKV


Consistent Hashing based Key-Value Memory Storage

基于一致性哈希的分布式内存键值存储——CHKV
目前的定位就是作为 CacheDataBase 的功能先不考虑。

系统设计

  • NameNode : 维护 DataNode节点 列表,用心跳检测 DataNode(一般被动,被动失效时主动询问三次),节点增减等系统信息变化时调整数据并通知 Client
  • DataNode : 存储具体的数据,向 NameNode 主动发起心跳并采用请求响应的方式来实现上下线,便于 NameNode 发起挪动数据指令,实际挪动操作由 DataNode 自行完成;
  • Client : 负责向 NameNode 请求 DataNode 相关信息并监听其变化,操纵数据时直接向对应 DataNode 发起请求就行,
    目前支持set,get,delete,keys,expire几个操作;

NameNode 失效则整个系统不可用。

若当成内存数据库使用,则要注意持久化,而且只要有一个 DataNode 失效(未经请求与数据转移就下线了)整个系统就不可对外服务;
若当成内存缓存使用,则 DataNode 失效只是失去了一部分缓存,系统仍然可用。

DataNode 失效(未经请求与数据转移就断开了和 NameNode 的连接)则 NameNode 需要及时通知 Client

客户 要使用 CHKV 就必须使用 Client 库或者自己依据协议(兼容redis)实现,可以是多种语言的API。
当然也可以把 Client 当做 Proxy,使得 CHKV 内部结构对 客户 透明,亦即有如下两种方式:


后端好书阅读与推荐(续五)


后端好书阅读与推荐系列文章:
后端好书阅读与推荐
后端好书阅读与推荐(续)
后端好书阅读与推荐(续二)
后端好书阅读与推荐(续三)
后端好书阅读与推荐(续四)
后端好书阅读与推荐(续五)

Redis设计与实现

Redis设计与实现 (豆瓣): https://book.douban.com/subject/25900156/

通过前面这本书我们已经知道redis怎么用比较好了,现在我们来看看 Redis 的实现原理。这本书是作者自己看着源码写出来的,不得不佩服作者的智慧与毅力。这本书基于redis3.0,此刻redis最新版是4.0.9,我们看书的时候可以自己去看看源码,看看redis有啥变化没,源码在此


分布式一致性机制整理


分布式中一致性是非常重要的,分为弱一致性强一致性。现在主流的一致性协议一般都选择的是弱一致性的特殊版本:最终一致性。下面就从分布式系统的基本原则讲起,再整理一些遵循这些原则的协议或者机制,争取通俗易懂。但是要真正实施起来把这些协议落地,可不是一片文章能说清楚的,有太多的细节,要自己去看论文呐(顺着维基百科找就行了)。

基本原则与理论

CAPConsistency一致性,Availability可用性,Partition tolerance分区容错性)理论是当前分布式系统公认的理论,亦即一个分布式系统不可能同时满足这三个特性,只能三求其二。对于分布式系统,P是基本要求,如果没有P就不是分布式系统了,所以一般都是在满足P的情况下,在CA之间寻求平衡。

ACIDAtomicity原子性,Consistency一致性,Isolation隔离性,Durability持久性)是事务的特点,具有强一致性,一般用于单机事务,分布式事务若采用这个原则会丧失一定的可用性,属于CP系统。

BASEBasically Availabe基本可用,Soft state软状态,Eventually consistency最终一致性)理论是对大规模的互联网分布式系统实践的总结,用弱一致性来换取可用性,不同于ACID,属于AP系统。


源码分析JDK8之AbstractQueuedSynchronizer


前言

源码分析我认为主要有两个作用:满足好奇心,我想每一个有追求的人都不会满足于仅仅做一个API Caller实现功能就好,我们也想知道它到底是怎么实现的;借鉴与升华,当我们明白了一个类的设计原理,在一定的情境下我们可以借鉴其设计哲学,甚至针对我们自己特殊的业务场景对其进行改良与优化。

下面我就以这篇文章开启我的源码阅读之旅。总体而言,我会从这个类基本结构入手,然后分析原理,再看看已有的应用,并进行分析与理解。

我之前一篇文章里提到过java的显示锁ReentrantLock。此外,如果你编写过并发程序那你一般也应该用过CountDownLatch,Semaphore等等,这些都是同步器,而它们都基于AbstractQueuedSynchronizer(简称AQS)实现的,那么我们今天就来看看这个牛逼的AQS是怎么实现这么多功能的。

首先打开IDEA,随便新建一个类,然后输入CountDownLatch,在它上面敲下Ctrl+B,就打开了CountDownLatch的源码,然后发现有一个非常重要的静态内部类Sync继承了AbstractQueuedSynchronizer,再次Ctrl+B,我们就打开了AQS的源码,马上就可以解开它的神秘面纱了,哼哼。

映入眼帘的首先就是大段大段的文档,大意就是这个类 提供了一个基于FIFO队列的实现了阻塞锁和相关同步器(信号量,事件等)的框架...... 读完了大概就了解这个类到底是怎么工作的了。下面我们开始分类型研究源码,当然不可能全部分析一遍,这里只把重点的列出来。