最近开发了一个既要高并发写又要高并发读的项目,写的QPS比读还要高,这个需求几乎是变态的,任何缓存的工具都没法使用,数据在一秒内可能变化的几十遍,只能每次请求都实时从数据库读取。下面分如下几点介绍我们是如何技术选型的。
一、选择通信协议
之前写的项目并发量很小,http+keepalive完全可以搞定了,此项目http完全架不住,因为使用http协议传递数据,那么数据最友好的格式就是json,但是亲测过json的序列化和反序列化的耗时不可以忍受,并且随着数据量的增大耗时也将成倍增长,项目的实际应用场景在写操作时每条数据最大在10KB,因此http+json的组合被kill掉。
只能选择常见的RPC方式,thrift、protobuf,protobuf需要自己实现tcp的通信方式,我们项目使用的是golang开发,这两种方式之前都没有在生产环境使用过,thrift仅仅自己玩过,因此就直接选择了thrift,编码的量级也相比protobuf降低好多,不过在代码写差不多的时候发现golang有基于protobuf开源的gRpc包。。。
通信协议选择了thrift,基本确定了C+S的架构模式,Client负责业务端的访问请求(还是走的http,貌似业务那帮人只会写业务逻辑,完全不懂架构的东西,如果懂Client都可以干掉,自己连Server就搞定了),Server负责Client通过thrift协议发来的请求,包括查询DB和计算。
二、选择数据库
数据库貌似没得选啊,MySQL肯定是可以的,但是需要对一条完整的业务数据进行拆分到多个表中,这对高并发写可能会有影响,一次要锁住多个表的多条数据,对代码的要求肯定很高,具体没有尝试过,只是猜测。MySQL的存储方案一直都没有被考虑过。
我们选择的是mongodb,版本是3.2.11,NOSQL数据库,支持嵌套文档,所有的写操作都可以通过upsert搞定,将并发写的代码要求交给mongo去完成,这样大大降低了编码的难度,mongo也属于内存型数据库吧,数据的读写速度还算可以(但是读的速度还是达不到我们项目的要求。。)