"软件开发没有银弹,咱们能作的就是选择和平衡;"html
上一篇文章咱们聊了在单线程下程序优化的5个方向(ref:《程序优化的5个方向》);当单核优化到极值后,就到了多任务的状况;
想起来很清晰,单个任务分解成多个任务,让多个cpu同时来工做,并行执行,效率天然就上去了;
但,未必就这么简单;git
首先,咱们须要肯定,咱们的单个任务是否能够分解;好比解析不少个文件,这样的任务划分红多个很简单;但若是是一个耗时的串行逻辑计算,后期的计算依赖前期的结果,这样就很差拆分;这种形式可能须要在更高层次上来拆分;github
编程就是计算和数据;计算并行了,但数据仍是访问同一份,访问共同的资源会产生资源竞争;
若是不进行控制,可能致使同一份数据重复计算(多个读的场景)或是脏数据的产生(有回写的场景);数据库
为了让数据访问有序进行,须要引入锁来防止脏数据;
控制锁的粒度,是个须要精心考虑的话题;
好比对于大量读少许写的场景,相比一视同仁的加锁,使用读写锁能显著提高效率;
咱们平常能接触到的产品中,数据库是个用锁高手,在更新数据的时候,是锁住行,仍是列、或是表,不一样的粒度性能相差明显;编程
考虑这样的场景:多个线程都在等在一个锁,若是能够拿到锁,线程就开始工做(线程池)
当锁被释放时,若是唤醒多个线程可能会产生 惊群现象;
解决方案:
使用单线程方案/处理accpet链接 处理等待锁的操做,让任什么时候刻只有一个线程在等待锁;
更多细节参考:
《客户-服务器程序设计方法》中 预先建立线程池,每一个线程各自accept 一节服务器
让每一个线程使用本身的数据,让数据不共有,这样能去掉资源竞争,去掉锁;
将数据复制为多份,减小竞争,各自访问各自的数据;
但这又引入了一个新的问题:若是各个线程回写了数据,如何保证这么数据的一致性?
毕竟它们表明的实际上是一份数据;架构
涉及到数据的一致性,多份数据之间的同步又是个难题;性能
那好,换个思路,不使用数据复制;咱们使用数据分片;分片这个思想更容易想到,既然“计算”被划分为多个小任务了,那么数据也能够一样处理;
将数据分片,每份数据存的内容不相同,它们之间没有共同点;
这样,数据访问没有数据竞争,同时因为数据不一样,也不涉及到数据一致性同步的问题;
但,分片远远没有想的那么美好;
分片致使了每一个线程看到数据再也不是全集,而是片断;这就注定了这个线程只能处理这部分的特定数据;这样,线程之间的计算失去了可替换性;某种工做只能在特定的线程上处理;
而若是有个任务须要访问全部的数据,这样就变得更加复杂;
原来,分片以后,咱们将难题向上推了,推到线程层面,须要考虑到业务逻辑层面的处理;
这样,可能更加复杂;优化
ok,想要速度更快,使用多核来处理,须要面对更多的问题;
将单机扩展多机集群,涉及到架构层面来看,其实咱们的面对的问题是相似的;
参考:《大型网站技术架构》读书笔记[2] - 架构的模式网站
软件开发没有银弹,咱们能作的就是选择和平衡;
Posted by: 大CC | 13AUG,2015
博客:blog.me115.com [订阅]
Github:大CC