摘要: Spanner要满足的external consistency是指:后开始的事务一定可以看到先提交的事务的修改。所有事务的读写都加锁可以解决这个问题,缺点是性能较差。特别是对于一些workload中只读事务占比较大的系统来说不可接受。为了让只读事务不加任何锁,需要引入多版本。在单机系统中,维护一个递 阅读全文
posted @ 2014-07-25 21:41 吴镝 阅读(15596) 评论(3) 推荐(1) 编辑
摘要: Redis Cluster是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由crc16(key) % 16384 决定。 关于负载均衡,集群的Redis Instance之间可以迁移数 阅读全文
posted @ 2014-04-08 19:54 吴镝 阅读(11901) 评论(0) 推荐(0) 编辑
摘要: twemproxy是twitter开源的redis/memcached 代理,数据分片提供取模,一致性哈希等手段,维护和后端server的长连接,自动踢除server,恢复server,提供专门的状态监控端口供外部工具获取状态监控信息。代码写的比较漂亮,学习了一些Nginx的东西,比如每个请求的处理分为多个阶段,IO模型方面,采用单线程收发包,基于epoll事件驱动模型。文档中提到的Zero Copy技术,通过将消息指针在3个队列之间流转实现比较巧妙。本文主要分析twemproxy的核心部分,即一个请求的从接收到最后发送响应给客户端的流程。一、大体流程 twemproxy后端支持多个serv. 阅读全文
posted @ 2014-04-08 14:00 吴镝 阅读(5725) 评论(0) 推荐(0) 编辑
摘要: 一致性问题要求多个process对一个值达成一致。基于消息传递的分布式系统中,在不考虑消息篡改等拜占庭错误的情况下,Paxos可以解决在进程退出,消息延迟,丢失,重复等异常发生的环境中对某个值达成一致的问题。考虑Paxos最基本的形式:两个角色:Proposer和Acceptor,Proposer提... 阅读全文
posted @ 2014-01-19 11:36 吴镝 阅读(2223) 评论(1) 推荐(0) 编辑
摘要: UpdateServer(UPS) 是OceanBase 的写入单点,一个集群中只有一台UPS服务器,所有的写都写入到这台机器。OceanBase采用基于静动态数据分离的机制,静态数据存储在静态数据服务器ChunkServer(CS)磁盘上,动态数据存储在UPS的内存中,导致一次读请求需要将静态和动态数据合并才能得到完整的数据,从而读也要访问UPS。OceanBase作为一个支持事务的分布式关系型数据库,UPS是实现事务的核心组件。单独看UPS,它是一个内存数据库,存储模型类似于LSM,写入操作写入内存,持久化通过写操作日志来保证,宕机后通过回放操作日志恢复数据,同时将对磁盘的随机写转换成顺. 阅读全文
posted @ 2014-01-10 13:38 吴镝 阅读(1916) 评论(0) 推荐(0) 编辑
摘要: 线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换。线程在等待IO操作时线程变为unrunnable状态会触发上下文切换。现代操作系统一般都采用抢占式调度,上下文切换一般发生在时钟中断和系统调用返回前,调度器计算当前线程的时间片,如果需要切换就从运行队列中选出一个目标线程,保存当前线程的环境,并且恢复目标线程的运行环境,最典型的就是切换ESP指向目标线程内核堆栈,将EIP指向目标线程上次被调度出时的指令地址。 协程也叫用户态线程,协程之间的切换发生在用户态。在用户态没有时钟中断,系统调用等机制,那么协程切换由什么触发?调度器将控制权交给某个协程后,.. 阅读全文
posted @ 2014-01-08 21:51 吴镝 阅读(11665) 评论(4) 推荐(3) 编辑
摘要: 在并发写Btree原理剖析一文中提到,节点内存回收有可能导致内存突增以及影响写性能。本文将阐述最近对内存回收的改进,多线程可并行回收内存。回收策略 采用基于版本的机制,Btree全局维护一个版本号V,一个全局数组A,每个线程一个槽位,每个线程读写操作之前获取全局版本号V,记作V0,并且记录到全局数组A中自己所属的槽位,表明对应线程不会再访问版本号V0之前的节点。写操作结束后,获取全局版本号V记录到这次写操作的TRecycleNode中,然后将V原子加1,这样来推进Btree的版本号递增,最后将这个TRecycleNode挂在线程局部的TRecycleNode的链表尾部。回收内存时,只需要遍历. 阅读全文
posted @ 2014-01-05 15:08 吴镝 阅读(1696) 评论(1) 推荐(0) 编辑
摘要: 转载自:http://coolshell.cn/articles/9703.html在《疫苗:Java HashMap的死循环》中,我们看到,java.util.HashMap并不能直接应用于多线程环境。对于多线程环境中应用HashMap,主要有以下几种选择:使用线程安全的java.util.Hashtable作为替代。使用java.util.Collections.synchronizedMap方法,将已有的HashMap对象包装为线程安全的。使用java.util.concurrent.ConcurrentHashMap类作为替代,它具有非常好的性能。而以上几种方法在实现的具体细节上,都或 阅读全文
posted @ 2013-12-29 12:49 吴镝 阅读(1232) 评论(0) 推荐(0) 编辑
摘要: lock free数据结构一般来说拥有比基于lock实现的数据结构更高的性能,但是其实现比基于lock的实现更为复杂,需要处理的难题包括预防ABA问题,内存如何重用和回收等。通常,最简单最有效的处理ABA问题的方法是在目标内存区域加入一个tag,每次目标内存区域被更新或者被重用时增加tag。线程最后一次读取目标内存区域后tag没有改变,CAS操作才能成功。比如对于无锁链表来说,目标内存区域就是链表节点。 但是,在目标内存区域中包含tag这种方法,当所有线程都不再需要使用某块内存区域时,没有机制可以检测。这也就导致这块内存区域不能被释放给系统供其他模块使用。hazard pointer可以用.. 阅读全文
posted @ 2013-12-28 17:50 吴镝 阅读(2310) 评论(1) 推荐(0) 编辑
摘要: OceanBase 0.4的UpdateServer存储引擎使用了一棵可以多线程并发修改的BTree,读写不冲突,由颜然开发。线上运行稳定。UpdateServer存储引擎采用类leveldb的方式,最近的更新操作都写入内存中的一个活跃memtable,当活跃memtable占用内存达到某个阈值时,... 阅读全文
posted @ 2013-12-06 16:55 吴镝 阅读(3715) 评论(0) 推荐(1) 编辑