分布式系统设计实践
基本的理论和策略简单介绍这么多,后面本人会从工程的角度,细化说一下”数据分布“、”副本控制”和”高可用协议”
在分布式系统中,无论是计算还是存储,处理的对象都是数据,数据不存在于一台机器或进程中,
. . .
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。
工厂模式可以分为三类:
简单工厂模式 (Simple Factory, 简单工厂模式可看为工厂方法模式的一种特例,两者归为一类。 )
工厂方法模式 (Factory Method)
抽象工厂模式 (Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。
简单工厂模式 :
一个工厂类, 这个工厂类能创建多个具体产品类的实例。
一个抽象产品类,可以派生出多个具体产品类。
工厂方法模式 :
一个抽象工厂类,可以派生出多个具体工厂类。
一个抽象产品类,可以派生出多个具体产品类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式 :
一个抽象工厂类,可以派生出多个具体工厂类。
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
<?php |
/** |
/** |
<?php |
/** |
/** |
<?php |
/* |
/* |
一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力。当对象们连接在一起时,它们就可以相互提供服务和信息。
通常来说,当某个对象的状态发生改变时,你仍然需要对象之间能互相通信。但是出于各种原因,你也许并不愿意因为代码环境的改变而对代码做大的修改。也许,你只想根据你的具体应用环境而改进通信代码。或者,你只想简单的重新构造通信代码来避免类和类之间的相互依赖与相互从属。
当一个对象的状态发生改变时,你如何通知其他对象?是否需要一个动态方案――一个就像允许脚本的执行一样,允许自由连接的方案?
观察者模式 :定义对象间的一种一对多的依赖关系, 当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
观察者模式允许一个对象关注其他对象的状态,并且,观察者模式还为被观测者提供了一种观测结构,或者说是一个主体和一个客体。主体,也就是被观测者,可以用来联系所有的观测它的观测者。客体,也就是观测者,用来接受主体状态的改变 观测就是一个可被观测的类(也就是主题)与一个或多个观测它的类(也就是客体)的协作。不论什么时候,当被观测对象的状态变化时,所有注册过的观测者都会得到通知。
观察者模式将被观测者(主体)从观测者(客体)种分离出来。这样,每个观测者都可以根据主体的变化分别采取各自的操作。(观察者模式和 Publish/Subscribe 模式一样,也是一种有效描述对象间相互作用的模式。)观察者模式灵活而且功能强大。对于被观测者来说,那些查询哪些类需要自己的状态信息和每次使用那些状态信息的额外资源开销已经不存在了。另外,一个观测者可以在任何合适的时候进行注册和取消注册。你也可以定义多个具体的观测类,以便在实际应用中执行不同的操作。
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
在以下任一情况下可以使用观察者模式:
观察者模式包含如下角色:
Observer 模式允许你独立的改变目标和观察者。你可以单独复用目标对象而无需同时复用其观察者, 反之亦然。它也使你可以在不改动目标和其他的观察者的前提下增加观察者。
下面是观察者模式其它一些优点 :
观察者模式的缺点 :
简单的更新协议不提供具体细节说明目标中什么被改变了 , 这就使得上述问题更加严重。如果没有其他协议帮助观察者发现什么发生了改变,它们可能会被迫尽力减少改变。
在 php 的 SPL 支持观察者模式,SPL 提供了 SplSubject 和 SplObserver 接口。
SplSubject 接口提供了 attach()、detach()、notify() 三个方法。而 SplObserver 接口则提供了 update() 方法。
SplSubject 派生类维护了一个状态,当状态发生变化时 - 比如属性变化等,就会调用 notify() 方法,这时,之前在 attach() 方法中注册的所有 SplObserver 实例的 update() 方法就会被调用。接口定义如下:
<?php |
实现代码:
<?php |
我们扩展上面的例子,根据目标状态而更新不同的观察者:
<?php |
通过 Observer 模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放 - 封闭原则。
CAP是分布式系统里最著名的理论,wiki百科如下
(摘自 :http://en.wikipedia.org/wiki/CAP_theorem)
. . .
分布式可繁也可以简,最简单的分布式就是大家最常用的,
在负载均衡服务器后加一堆web服务器,然后在上面搞一个缓存服务器来保存临时状态,
后面共享一个数据库,其实很多号称分布式专家的人也就停留于此,
大致结构如下图所示:
这种环境下真正进行分布式的只是web server而已,
并且web server之间没有任何联系,所以结构和实现都非常简单。
有些情况下,对分布式的需求就没这么简单,
在每个环节上都有分布式的需求,
比如Load Balance、DB、Cache和文件等等,
并且当分布式节点之间有关联时,
还得考虑之间的通讯,
另外,
节点非常多的时候,
得有监控和管理来支撑。这样看起来,
分布式是一个非常庞大的体系,
只不过你可以根据具体需求进行适当地裁剪。按照最完备的分布式体系来看,
可以由以下模块组成:
分布式任务处理服务:负责具体的业务逻辑处理
分布式节点注册和查询:负责管理所有分布式节点的命名和物理信息的注册与
询,是节点之间联系的桥梁
分布式DB:分布式结构化数据存取
分布式Cache:分布式缓存数据(非持久化)存取
分布式文件:分布式文件存取
网络通信:节点之间的网络数据通信
监控管理:搜集、监控和诊断所有节点运行状态
分布式编程语言:用于分布式环境下的专有编程语言,比如Elang、Scala
分布式算法:为解决分布式环境下一些特有问题的算法,比如解决一致性问题的Paxos算法
其实,分布式系统说白了,就是很多机器组成的集群,靠彼此之间的网络通信,担当的角色可能不同,共同完成同一个事情的系统。
. . .
只谈一下单链表, 链表实在是太重要, 是前面两篇说算法博客的基础, 了解了其应用和衍生, 再去了解其本身就有动力了
typedef struct Node |
头结点的优点:
include <stdio.h> |
运行结果:3 2 1
0 3 2 1
提示:没有 0 的为无头结点的头插法输出结果,有 0 的为有头结点的头插法的输出结果
. . .