终于理解了CAP定理

Brewer最早的ppt讲得太泛了,看了还是不明白。后来看了很多相关的文章,才明白了这个东西。 为了不走弯路,首先你要明白Partition是 指什么。它不是“分区容忍性”,而是对“系统内部结点间通信失败的容忍性”。 其次,CAP所针对的分布式系统是跟数据相关的,要么这个系统直接存储了数据,要么它会把数据存储到另外的系统中,这样才有必要谈C(数据一致性)。无状态的分布式应用是没有资格谈CAP的。 再次,3″取”2 这种说法是很含混的,不要过分纠结。以mysql服务为例, 1. 如果说舍弃P,那仅仅意味着你的mysql是单机版的;单库可以利用事务直接保证C,而且你可以通过scale up来获得A. 这种情况下,你的应用并不是一个分布式应用。 2. 如果要保留P,也仅仅是指mysql使用了读写分库或者其他分拆方案。什么叫耐受,什么叫不耐受,并没有明确的定义。它只是给你提供一个将讨论持续下去的基础,也就是说,在分拆之后,你才可以开始谈“在A和C之间取舍”。 以读写分库为例,当主备库之间网络断裂时, a.如果你仍然允许主库写、备库读,则主备库都是高可用的,但主备库数据却由于无法同步而出现了不一致,也就是说,有A无C. b.如果你不允许主库写,则在用户眼里写操作就不是可用的了,但是主备库的数据却保证了一致性,也就是说,有C无A. 总结一下:在分布式应用中,P是天然存在的,而所谓的Trade-Off是指A和C之间的取舍。 最后要说明一下,“有A无C”、”有C无A”以及“无法同步”都是比较极端的情况,在实践中,尤其是高并发的应用中,你面临的更多是“A强C弱“、”C强A弱“(A的强弱即系统响应的快慢)、“同步时延很高”这些灰色的东西。

应该来一个请求起一个线程池,还是做一个大池用来响应所有请求?

你的应用是这样的:    1. 接收浏览器的请求    2. 多线程地从后端获取数据    3. 把数据给浏览器 你的应用应该来一个请求起一个线程池,还是做一个大池用来响应所有请求? 我做了一点实验,发现两种选择对单个请求的Latency没有什么影响。 不过,为了防止高并发时,过多线程池并存导致过高的总线程数,建议还是使用后者:一个大池响应所有请求。 2013/3/28补充: 看了《JAVA并发编程实践》6.1节,你会更加反对“一个请求一个线程池”机制。    1. 创建新线程需要时间,而且比较可观    2. 线程数据结构会占用内存:除了linux内核中task_struct这个结构,还包括JVM栈中的数据结构,如果-Xss设置的不够大,可能引发JVM栈上的OOM.    3. 线程太多,也带来上下文切换的开销。

Btrace常用片断

imports 引用 import static com.sun.btrace.BTraceUtils.*; import java.sql.Statement; import java.util.Map; import com.sun.btrace.AnyType; import com.sun.btrace.aggregation.Aggregation; import com.sun.btrace.aggregation.AggregationFunction; import com.sun.btrace.aggregation.AggregationKey; import com.sun.btrace.annotations.*; Class declaration 引用 @BTrace public class JdbcQueries {   … } OnMethod 引用     @OnMethod(         clazz="+java.util.logging.Logger",         method="log"     )     public static void onLog(@Self Logger self, LogRecord record) {         println(Reflective.get(msgField, record));     } …

Btrace常用片断 Read More »

我对ACID的理解

发现自己对数据库事务ACID的理解其实点模糊。今天参阅了Kroenke的《数据库原理》和其它一些材料后,总结如下: Atomicity 这个最好理解,不用说 ====================================================== Durability 这个有两层意思:   1.事务一旦完成,改动就被持久化了,数据库重启后,数据还在那 (简直是废话,但正因为像废话,才容易让人迷惑)   2. 有的DBMS可以在突然断电时根据事务日志什么的修复数据 ====================================================== Isolation 如果你问自己“什么叫两个事务有互相隔离,什么叫无互相隔离?”,你就会陷入晕眩。 因为这是个伪问题。隔离性不是有没有的问题,而是高不高的问题。 ANSI定义了4种隔离级别,最低叫脏读,最高叫序列化。 并发事务可能在最低级别上运行,也可能在最高级别上运行。 而即使在最低级别上运行,它们也是事务。 ======================================================= Consistency 这是最难让人迷惑的问题,因为"Consistent"在汉语里其实没有关于它的用法。如果你跟人说“一致”,别人只能想到“两个值相同就叫一致”,但这跟事务的一致性好像没什么联系。。。 在我看来, 数据库的一致性是指 事务看到的两个值“总是同一个时间点的值”,也就是说,你在10点钟读记录A,11点钟读记录B,如果读得的B的值是10点钟的B的值,那就是有了一致性;如果读的是11点钟的值,那就可能不一致。 引用 初始值: Ra=100, Rb=50 10点钟执行语句:select R … where id in (a, b) ,先读到了Ra=100 由于某种原因,11点前本查询暂时卡住了 10点半:另一个事务set Rb = 200 并提交 11点钟本查询才继续执行,并读到了Rb. Rb = ?  如果Rb=200,就是不一致,因为200并不是本查询语句启动时的值(10点钟,50) 上面就是“Statement-Level Read Consistency”,即同一个语句里面读到的所有值都是同一个时间点的值 另外有一种级别的一致性,叫“Transaction-Level Read Consistency” …

我对ACID的理解 Read More »

lvs集群中的心跳用什么来实现?

答:keepalived. 在lvs集群中它提供了两种结点健康相关的应用:   1. 监视server pool里各结点的状态,以供load balancer略过不健康的server   2. 通过VRRP协议实现loader balancer之间的主备切换(failover)

有了第4层负载均衡为什么还要做第7层的负载均衡?

有了第4层负载均衡(比如lvs),为什么还要做第7层的(比如nginx, squid)? 第4层负载确实已经能做到比较全面了,但不方便做app-specific的均衡策略。 比如“凡是URL以detail.*开头的请求都导到A1-A10结点”,用lvs等就不方便做。然而,用nginx等就比较好实现。  也就是说 第7层负载可以实现更加灵活的、与应用层信息相关的均衡策略。

CPU的us和sy高对于JAVA应用来说分别意味着什么?

以下内容来自林昊的《分布式JAVA应用》 us高代表用户态程序占CPU的比例较高 sy高代表内核态程序占CPU的比例较高 对java应用来说, us高一般是因为    1. 有些线程一直处于可运行状态,比如使劲循环    2. CPU密集型操作太多,比如正则运算    3. 频繁GC sy高一般是因为线程上下文切换过于频繁。而切换过多,一般是由于过多阻塞导致的,包括锁等待、I/O阻塞等,一个线程的阻塞会导致CPU让另一个线程上位,即上下文切换。 p.s. sy高跟系统调用过多也会有关系

哈希表里的bucket是指什么东西?

转自维基百科: http://en.wikipedia.org/wiki/Hash_function In general, a hashing function may map several different keys to the same index. Therefore, each slot of a hash table is associated with (implicitly or explicitly) a set of records, rather than a single record. For this reason, each slot of a hash table is often called a bucket, and hash values …

哈希表里的bucket是指什么东西? Read More »