#
传统MySQL+ Memcached架构遇到的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:
MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
Memcached与MySQL数据库数据一致性问题。
Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
跨机房cache同步问题。
众多NoSQL百花齐放,如何选择
最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问 题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决 以下几种问题
少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。
海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。
这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过 类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。
Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。
面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。
Redis适用场景,如何正确的使用
前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed 的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用 Memcached,何时使用Redis呢?
Redis与Memcached的比较
网络IO模型
Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接 描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如,Memcached最常用的stats 命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。

(Memcached网络IO模型)
Redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll、kqueue和 select,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是Redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操 作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞住的。
内存管理方面
Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存 储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数 据也可能会被剔除,原因可以参考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/
Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎 片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致 swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。
数据一致性问题
Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。
存储方式及其它方面
Memcached基本只支持简单的key-value存储,不支持枚举,不支持持久化和复制等功能
Redis除key/value之外,还支持list,set,sorted set,hash等众多数据结构,提供了KEYS
进行枚举操作,但不能在线上使用,如果需要枚举线上数据,Redis提供了工具可以直接扫描其dump文件,枚举出所有数据,Redis还同时提供了持久化和复制等功能。
关于不同语言的客户端支持
在不同语言的客户端方面,Memcached和Redis都有丰富的第三方客户端可供选择,不过因为Memcached发展的时间更久一 些,目前看在客户端支持方面,Memcached的很多客户端更加成熟稳定,而Redis由于其协议本身就比Memcached复杂,加上作者不断增加新 的功能等,对应第三方客户端跟进速度可能会赶不上,有时可能需要自己在第三方客户端基础上做些修改才能更好的使用。
根据以上比较不难看出,当我们不希望数据被踢出,或者需要除key/value之外的更多数据类型时,或者需要落地功能时,使用Redis比使用Memcached更合适。
关于Redis的一些周边功能
Redis除了作为存储之外还提供了一些其它方面的功能,比如聚合计算、pubsub、scripting等,对于此类功能需要了解其实现原理,清 楚地了解到它的局限性后,才能正确的使用,比如pubsub功能,这个实际是没有任何持久化支持的,消费方连接闪断或重连之间过来的消息是会全部丢失的, 又比如聚合计算和scripting等功能受Redis单线程模型所限,是不可能达到很高的吞吐量的,需要谨慎使用。
总的来说Redis作者是一位非常勤奋的开发者,可以经常看到作者在尝试着各种不同的新鲜想法和思路,针对这些方面的功能就要求我们需要深入了解后再使用。
总结:
Redis使用最佳方式是全部数据in-memory。
Redis更多场景是作为Memcached的替代者来使用。
当需要除key/value之外的更多数据类型支持时,使用Redis更合适。
当存储的数据不能被剔除时,使用Redis更合适。
后续关于Redis文章计划:
Redis数据类型与容量规划。
如何根据业务场景搭建稳定,可靠,可扩展的Redis集群。
Redis参数,代码优化及二次开发基础实践。
关于作者
田琪,目前负责新浪微博平台底层架构与研发工作,之前曾担任搜狐白社会实时游戏平台核心架构工作,主要关注webgame, 分布式存储,nosql 和 erlang 等领域,目前主要从事mysql源代码的一些深入研究工作,浪微博:http://weibo.com/bachmozart。
摘要: 简单来说,观察者模式=发布者+订阅者。下面是一个有关猎头的典型的例子。在下面这张图当中有两个角色:猎头和寻找工作的人。找工作的人向猎头订阅,告知自己希望得到一份工作,当有新的工作机会的时候,猎头就会把这个信息通知给曾经向他订阅过的人。Java代码Subject接口:1public interface Subject {2 publi...
阅读全文
$('#formID').on('submit',function () {
$.ajax({
url: 'submit.php',
cache: false,
type: 'POST',
data : $('#formID').serialize(),
success: function(json) {
alert('all done');
}
});
});
-----------------曾国藩箴言(一)----------------
●轻财足以聚人,律己足以服人,量宽足以得人,身先足以率人。
【译文】轻视财物可以召集人,律己可以让人敬服,气量宽广可以得人心,自己亲身先做事可以领导人。
●惟正己可以化人,惟尽己可以服人。
【译文】只有端正自己可以感化别人,只有开放自己的心才可以服人。
●遇诡诈人变幻百端,不可测度,吾一以至诚待之,彼术自穷。
【译文】遇到诡秘狡诈的人变化百端,不可以猜测度量,我都用至诚心对待他,他的方法就没用了。
●功不独居,过不推诿。
【译文】有功劳不自己一个人占有,有过错不推脱。
●不可轻率评讥古人。
【译文】不可以轻易评论讥讽古人。
●今日所说之话,明日勿因小利害而变。
【译文】今天讲的话,明天不要因为小的利害就改变。
●遇棘手之际,须从耐烦二字痛下功夫。
【译文】遇到棘手的时候,要从耐烦这两个字上下功夫。
●勿以小恶弃人大美,勿以小怨忘人大恩。
【译文】不要因为别人小的坏处而放弃他大的优点,不要因为与别人小的仇怨而忘记他的恩情。
-----------------曾国藩箴言(二)--------------------
●责过太直,使人惭恨,在我便是一过。
【译文】指责过错过于直接,让别人生惭愧而痛恨自己,对我来说就是一种过错。
●受挫受辱之时,务须咬牙励志,蓄其气而长其智。
【译文】受到挫败和侮辱时,一定要咬紧牙忍受来激励志向,继续志气,增长智慧。
●行事不可任心,说话不可任口。
【译文】做事不可以随心所欲,说话不可以随口胡说。
●百种弊病,皆从懒生。
【译文】很多的弊病都是从懒惰生出的。
●守笃实,戒机巧,守强毅,戒刚愎。
【译文】谨守笃定老实,不要投机取巧,尽收刚强坚毅,不要刚愎自用。
●凡人做一事,便须全副精神注在此一事,不可见异思迁。
【译文】凡是有人要做一件事,就须把全副精神贯注在这件事上,不可以见异思迁。
---------------曾国藩箴言(三)---------------
●寡言养气,寡视养神,寡欲养精。
【译文】少说话可以休养元气,少看可以休养心神,减少欲望可以休养精气。
●礼义廉耻,可以律己,不可以绳人。
【译文】礼义廉耻,可以用来要求自己,却不能用来要求别人。
●利可共而不可独,谋可寡而不可众。独利则败,众谋则泄。
【译文】利益可以共享不可以独享,谋划可以让少数人知道不可以让多数人知道,独享利益就会失败,谋划让多数人知道就会泄露。
●久利之事勿为,众争之地勿往。物极则反,害将及矣。
【译文】能一直产生利益的事不要做,众人争夺的好地方不要去。物极必反,祸害就要来了。
●知足则乐,务贪必忧。
【译文】知足就会快乐,执着贪心就会忧虑。
●处事宜决断。
【译文】处理事情应该坚决果断。
●事到手且莫急,便要缓缓想。想得时切莫缓,便要急急行。
【译文】事情分配到手上先别急,要慢慢想。想到时不要拖延,要赶快做。
●尖酸语称快一时,当之者终身怨恨。
【译文】尖酸刻薄的话让你一时痛快,可对方却终身怨恨你。
●凡权要人声势赫然时,我不可犯其锋,亦不可与之狎,敬而远之,全身全名之道也。
【译文】凡是掌握权力的重要人物声名、势力非常大的时候,我们不要去触犯他的锋芒,也不可以和他交好。对他敬而远之,是保全自己名声、生命的方法。
●行事常思退一步。
【译文】做事常常要想到退让一步。
●慎言谨行,是修己第一事。
【译文】谨慎自己的言行,是修养自己德行的最重要的事。
logstash日志处理采用队列ZMQ,压力会很好的被缓冲,针对高并发的大数据量的日志处理是没有问题的,日志利用ES存放,就是个基于lucene的全文检索数据库,也不存在数据量的问题。
logstash 是一个应用程序日志、事件的传输、处理、管理和搜索的平台。
你可以用它来统一对应用程序日志进行收集管理,提供 Web 接口用于查询和统计。

方法一:循环元素删除
// 删除ArrayList中重复元素
public static void removeDuplicate(List list) {
for (int i = 0; i < list.size() - 1; i++) {
for (int j = list.size() - 1; j > i; j--) {
if (list.get(j).equals(list.get(i))) {
list.remove(j);
}
}
}
System.out.println(list);
}
方法二:通过HashSet剔除
// 删除ArrayList中重复元素
public static void removeDuplicate(List list) {
Set set = new HashSet(list);
list.clear();
list.addAll(set);
System.out.println(list);
}
方法三: 删除ArrayList中重复元素,保持顺序
// 删除ArrayList中重复元素,保持顺序
public static void removeDuplicateWithOrder(List list) {
Set set = new HashSet();
List newList = new ArrayList();
for (Iterator iter = list.iterator(); iter.hasNext();) {
Object element = iter.next();
if (set.add(element))
newList.add(element);
}
list.clear();
list.addAll(newList);
System.out.println(" remove duplicate " + list);
}
摘要: 除了传统对于远程调用的需求,近来移动开发对于api的规范化需要,restful作为一个流行的接口调用方式,值得深入了解。声明 本文属于转载:原文此文为实践总结,是自己在实践过程中积累的经验和"哲学"。部分内容参考相关资料,参考内容请看尾页。建议对RESTful有一定了解者阅读!"哲学"不要为了RESTful而RESTful在能表达清楚的情况下,简单就是美接口路径设计接口设计原则URI指向...
阅读全文
UML定义的关系主要有:泛化、实现、依赖、关联、聚合、组合,这六种关系紧密程度依次加强,分别看一下
1、泛化
概念:泛化是一种一般与特殊、一般与具体之间关系的描述,具体描述建立在一般描述的基础之上,并对其进行了扩展。在程序中是通过继承类实现的。比如狗是对动物的具体描述,在面向对象设计的时候一般把狗设计为动物的子类。
表示方法:空心三角形箭头的实线,子类指向父类

2、实现
概念:实现是一种类与接口的关系,表示类是接口所有特征和行为的实现,在程序中一般通过类实现接口来描述
表示方法:空心三角形箭头的虚线,实现类指向接口

3、依赖
概念:是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖,在程序中一般表现为类A中的方法需要类B的实例作为其参数或者变量,而类A本身并不需要引用类B的实例作为其成员变量。
表示方法:虚线箭头,类A指向类B。

4、关联
概念:表示类与类之间的联接,它使一个类知道另一个类的属性和方法,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,在程序中被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量
表示方法:实线箭头,类A指向类B

5、聚合
概念:聚合关联关系的一种特例,是强的关联关系。聚合是整体和个体之间的关系,即has-a的关系,整体与个体可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。程序中聚合和关联关系是一致的,只能从语义级别来区分;
表示方法:尾部为空心菱形的实线箭头(也可以没箭头),类A指向类B

6、组合
概念:组合也是关联关系的一种特例。组合是一种整体与部分的关系,即contains-a的关系,比聚合更强。部分与整体的生命周期一致,整体的生命周期结束也就意味着部分的生命周期结束,组合关系不能共享。程序中组合和关联关系是一致的,只能从语义级别来区分。
表示方法:尾部为实心菱形的实现箭头(也可以没箭头),类A指向类B
