摘要: 理解分布式一致性与Raft算法 永远绕不开的CAP定理 出于可用性及负载方面考虑,一个分布式系统中数据必然不会只存在于一台机器,一致性简单地说就是分布式系统中的各个部分保持数据一致 ![1 1PF3102KOJ.jpg 18kB][1] 但让数据保持一致往往并不像看上去那么简单,假设我们有两台机器A 阅读全文
posted @ 2019-08-06 10:12 吴纹羽 阅读(5545) 评论(0) 推荐(1) 编辑
摘要: 关联文章索引:大数据时代的数据存储,非关系型数据库MongoDB性能与用户量 “如何能让软件拥有更高的性能?”,我想这是一个大部分开发者都思考过的问题。性能往往决定了一个软件的质量,如果你开发的是一个互联网产品,那么你的产品性能将更加受到考验,因为你面对的是广大的互联网用户,他们可不是那么有耐心的... 阅读全文
posted @ 2014-12-16 14:30 吴纹羽 阅读(32452) 评论(22) 推荐(40) 编辑

其实从一开始了解到go的goroutine概念就应该想到,其实go应该就是在内核级线程的基础上做了一层逻辑上的虚拟线程(用户级线程)+ 线程调度系统,如此分析以后,goroutine也就不再那么神秘了。

并发≠并行

假如我们有一段CPU密集型任务,我们创建2000个gorountine是否真的可以将其性能提高2000倍,答案必然是不能,因为我们只是进行了2000次的并发(concurrency),而并没有真正做到并行(parallelism)。

并发其实所指的是我们的程序执行逻辑,传统单线程应用的程序逻辑是顺序执行的,在任何时刻,程序只能处理同一个逻辑,而并发指的是,我们同时执行多个独立的程序逻辑,若干个程序逻辑在执行时可以是同时进行的(但并不代表同时进行处理)。实际上,不论我们并发多少个程序逻辑,若我们仅仅将其运行在一个单核单线程的CPU上,都不能让你的程序在性能上有所提升,因为最终所有任务都排队等待CPU资源(时间片)。

而并行才能让我们的程序真正的同时处理多个任务,但并行并不是编程语言能够带我们的特性,他需要硬件支持。上面说到单核CPU所有资源都要等待同一个CPU的资源,那么其实我们只要将CPU增多就能真正的让我们实现并行。我们可以使用多核CPU或用多台服务器组成服务集群,均可实现真正的并行,能够并行处理的任务数量也就是我们的CPU数量。

引用Rob Pikie大神在PPT《Concurrency is not Parallelism》中的一段总结,大意就是并发不同于并行,但并发也许可以让程序实现并行化。

Concurrency vs. parallelism
Concurrency is about dealing with lots of things at once.

Parallelism is about doing lots of things at once.

Not the same, but related.

Concurrency is about structure, parallelism is about execution.

Concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable.

CPU密集&I/O密集

那么是不是说我们在单核CPU的机器上使用编程语言所提供的多线程就没有意义了呢?

如果说我们的程序属于CPU密集型,使用并发编程,可能确实无法提升我们的程序性能,甚至可能因为大量计算资源花在了创建线程本身,导致程序性能进一步下降。

但不同的是,如果说我们的程序属于IO密集型,当你在进行程序压测的过程中可能发现CPU占用率很低,但性能却到了瓶颈,原因是程序将大量的时间花在了等待IO的过程中,如果我们可以在等待IO的时候继续执行其他的程序逻辑即可提高CPU利用率,从而提高我们的程序性能,这时并发编程的好处就出来了,例如Python因为GIL的存在实际上并不能实现真正的并行,但他的多线程依旧在IO密集型的程序中依旧有种很重要的意义。

Goroutine(Golang Coroutine)

上面说到了使用多核CPU实现并行处理,使应用在多核cpu实现并行处理的方案主要是多进程与多线程两种方式,多进程模型相对简单,但是有着资源开销大及进程间通信成本高的问题。多线程模型相对复杂,会有死锁,线程安全,模型复杂等问题,但却因为资源开销及易于管理等优点适用于对于性能要求较高的应用。

Golang采用的是多线程模型,更详细的说他是一个两级线程模型,但它对系统线程(内核级线程)进行了封装,暴露了一个轻量级的协程goroutine(用户级线程)供用户使用,而用户级线程到内核级线程的调度由golang的runtime负责,调度逻辑对外透明。

goroutine的优势在于上下文切换在完全用户态进行,无需像线程一样频繁在用户态与内核态之间切换,节约了资源消耗。

同时,启动一个gorountine非常简单,而且写法很cool~

go function()

仅仅需要在调用函数时在前面加上关键字go即可创建一个goroutine并创建其上下文对象。

G·P·M

G(Goroutine) :我们所说的协程,为用户级的轻量级线程,每个Goroutine对象中的sched保存着其上下文信息

M(Machine) :对内核级线程的封装,数量对应真实的CPU数(真正干活的对象)

P(Processor) :即为G和M的调度对象,用来调度G和M之间的关联关系,其数量可通过GOMAXPROCS()来设置,默认为核心数

每个Processor对象都拥有一个LRQ(Local Run Queue),未分配的Goroutine对象保存在GRQ(Global Run Queue )中,等待分配给某一个P的LRQ中,每个LRQ里面包含若干个用户创建的Goroutine对象,同时Processor作为桥梁对Machine和Goroutine进行了解耦,也就是说Goroutine如果想要使用Machine需要绑定一个Processor才行,上图中共有两个M和两个P也就是说我们可以同时并行处理两个goroutine。

这一篇主要讲解了一些并行与并发的区别Golang并发模型的优势,下一篇会详细说明GPM模型的调度策略。

posted @ 2018-11-21 19:01 吴纹羽 阅读(12230) 评论(4) 推荐(5) 编辑
摘要: 解决的问题 一项技术的产生必然是为了解决问题而生,了解了一项技术解决的问题,就能够很轻松的理解这项技术的设计根本,从而更好地理解与使用这项技术。 消息中间件和RPC从根本上来说都是为了解决分布式系统的服务间通信问题,我们的服务从最初的单体应用发展到SOA架构到现在的微服务架构,必不可少的就是服务间通 阅读全文
posted @ 2018-05-21 08:15 吴纹羽 阅读(5491) 评论(4) 推荐(5) 编辑
摘要: 真正开始使用Linux是从2013年某月看到王垠写的一篇《完全用Linux工作》,当时属于无比崇拜王垠的阶段,虽然在那之前常年都在电脑上装着双系统(linux,win),但linux也只能在我电脑开机时选择系统的时候秀一下存在感罢了,因为我装完之后压根就没进过linux。看完《完全用Linux工作》 阅读全文
posted @ 2015-04-16 10:10 吴纹羽 阅读(13192) 评论(42) 推荐(7) 编辑
摘要: 曾经见到知乎上有人问“为什么像facebook这类的网站需要上千个工程师维护?”,下面的回答多种多样,但总结起来就是:一个高性能的web系统需要从无数个角度去考虑他,大到服务器的布局,小到软件中某个文件的实现,甚至于某个循环内的运算如果出现不严谨都可能导致全盘崩溃。 上面提到web性能优化需要... 阅读全文
posted @ 2015-04-14 10:18 吴纹羽 阅读(15462) 评论(47) 推荐(55) 编辑
摘要: 第二篇:开发高性能的MongoDB应用—浅谈MongoDB性能优化爆炸式发展的NoSQL技术 在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构。... 阅读全文
posted @ 2014-11-06 16:01 吴纹羽 阅读(23159) 评论(24) 推荐(66) 编辑
摘要: 在许多应用中需要频繁的创建许多生命周期很短的线程,如果用传统方法的话就会造成大量的资源了浪费,java的设计者们考虑到了这点在java中加入了线程池这个特性,它负责管理大量的线程的创建销毁等操作。 首先我们需要了解一个类:java.util.concurrent.Executors(执行器) ... 阅读全文
posted @ 2014-02-21 10:01 吴纹羽 阅读(4533) 评论(0) 推荐(3) 编辑
摘要: 也许大家有过在java运行平台上解析html的经历,通常的方式是将HTML以XML的形式进行结点解析,调用java本身的xml解析类库。这样的方式很容易理解并且很方便,但习惯用jQuery的各位是否在感叹能否在java中像jQuery一样获取标签内容,实现DOM操作呢?终于,发现了一个html解... 阅读全文
posted @ 2014-02-20 23:16 吴纹羽 阅读(11409) 评论(5) 推荐(4) 编辑
点击右上角即可分享
微信分享提示