Month: October 2012

CAS理解

本文基本节选自 Java theory and practice: Going atomic CAS字面上是什么意思? CAS = Compare-and-Swap. 它的语义是: public class SimulatedCAS { private int value; //如果某个值当前值是期望值,则将某个值设置为新值;否则不做设置. //然后,返回当前值 public synchronized int compareAndSwap(int expectedValue, int newValue) { int currentValue = value; if (value == expectedValue) value = newValue; return currentValue; } } CAS在并发控制上起什么作用? 以“自增操作”为例,使用CAS可以避免常见的“丢失修改”问题 private SimulatedCAS value; public int increment() { int oldValue …

CAS理解 Read More »

一些散乱的关于Eventual Consistency的笔记

1.对于跨数据库的业务操作,如果追求强一致性,就要走2PC(two-phase commit) 协议。而这个协议在Availability方面可能表现不佳:    a.只要一个库回滚,大家都得回滚    b.导致多处的资源上锁,影响性能 2.按不同的语境,弱一致性有两种含义:   a. 不要求所有子操作原子地执行。可以容忍有的操作成功,有的操作失败,比如用于估算的数据,可以允许零星的失败   b. 不要求在甲方扣款后乙方在同一瞬间收到款,可以允许乙方隔一段时间后(最终)收到款(即最终一致性) 3.“最终一致性”一般可以通过消息队列来实现:完成一个子操作后,发出一个消息,这个消息将被异步地处理   a. 即使一个系统挂了,也不会影响上游系统继续工作   b. 如果系统处理一个消息失败,可能需要重复处理这个消息。 所以最好把消息消费设计成Idempotent 参考资料: http://queue.acm.org/detail.cfm?id=1394128

CAP定理中的Partition不应该译成“分区”

“分区”是个中性词,不好也不坏。而CAP定理中的Partition代表的是一种“坏”的情况。 这里介绍说: 引用 A partition happens when, say, a network cable gets chopped, and Node A can no longer communicate with Node B. 可以看出,partition指的是两个结点之间无法互通,这可能是因为网络线路断开,也可能是因为其中一个结点出了故障。 这跟我们平常说的分区完全不是一回事。"partition"译成“阻断“才比较合适,或者干脆译成”结点间互联失败“;也只有这样译,它跟tolerance连起来用才有意义: “对网络通信的容忍度”可以理解, 而“对分区的容忍度”。。。这什么玩意?  这个错误的译法会让人坠入云里雾里,在阅读相关文献时抓破脑袋。从这个意义上说,第一个把"Partition Tolerance"译成“分区耐受性”的人,应该主动切腹以谢国人。

终于理解了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)