`
qiezi
  • 浏览: 492073 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
文章列表
十几个同事通宵。 运维一个新同事的误操作,让所有服务器都无法登录了,只能到机房一台台重启。 各业务负责人、测试部同事、DBA都通宵处理。 养足精神,1点就要开始战斗了。
最近在构思一个并行/分布式集群的平台架构,用来解决目前很多服务器无法动态扩容的问题,在过去的一些分布式项目中积累了一些经验,这些架构都是对这些项目共同点的抽象。 给它定义了一些特性,先记下来: * 集群由多台服务器组成,每台服务器安装最基本的运行时平台; * 平台负责集群内节点间通讯、应用实例的管理; * 平台是多进程架构,任何应用都是独立的用户进程,使用IPC来通讯; * 平台内底层通讯使用节点方式,类似Erlang的PID; * 应用的实例对Pid不可见,它一般只使用其它应用的接口,通过应用ID和接口来访问,不关心其它应用的部署位置,所有应用都是位置无关的; * 应用实例运行的位置由平台 ...
前几天睡不着时写的,发在公司博客上,转过来留作纪念。 推动一个这么大的设想直接立项还是很困难的,不过可以先把一些重要模块立项开发,时间成熟以后剩下的平台工作工作量就相对较少了。所以最要紧的是要把握住,不 ...
最近在测试简单的轻量级线程调度器。从fiber转换到generator,性能是提升了不少,但却在意想不到的地方出现了瓶颈。 在generator本身切换性能测试时,发现它性能非常高,大概单线程里面每秒切换有2亿次以上,比fiber的200-400万次有了质的提高。但是在实现了一个简单的调度器以后,发现性能急骤下降,到了每秒千万次,实现方式是使用标准库提供的list容器。 在测试了c++标准库的std::list和c#的几个list容器以后,发现它们性能都非常低,每秒仅能处理上千万次尾部添加和头部删除操作。简单分析后可以确认,性能降低是由于频繁的分配释放引起的,改用g++的ext/poll_a ...
前面说地Generator编写并发程序的优势,当然它本身没有这种能力,需要为它编写调度程序。 今天抽点时间写了个简单的,还是满好玩的,它可以调度多个“友好”的并发任务,包括: 1、用户自己编写的适时交出控制权的过程 2、网络IO 由于对C#不是很熟,所以写的可能比较难看,而且IO也只支持网络,有兴趣的可以研究改进一下,比如把它改成SMP版本,增加Actor模型,处理更多的IO模式等。 实现方式基本上是从IoLanguage里面抄过来的,我已经用它编写过Ruby/C++/D/C#版本,当然目前仅限于测试它的切换性能。 好消息是如果你实现得比较好,C#版本性能完全可以超过Erlang,Rub ...
一直没搞清云计算和网格计算的差别,为什么就提出个新词了呢? 通过对Amazon的Google的观察,发现这两家公司产品方向的一些共同点。 1、软件即服务 Google App Engine和Amazon SimpleDB/S3都是提供服务的,类似的例子还有最近比较火的各种开放接口。 2、应用容器,自动部署,超强的扩展能力 Google App Engine更能体现这点。由于开放的所有接口都是调用服务,应用运行的容器本身完全不需要保存任何状态,它只需要有强劲的CPU、内存和网络设备,任何时候都可以把服务横向扩展到多台服务器上。 3、后台技术 分布式文件系统,分布式DB,都需要提供超强的性能 ...
几种并发编程模型开销(从大到小): Process > Thread > Coroutine > Generator == Callback 从对机器的并行利用来说,却是完全相反的。 Process可以部署在不同机器上; Thread需要在Process里面,往往是很多Thread在一个Process里面,它对多CPU利用还是比较充分的; Coroutine在Thread里面运行,要利用多CPU,需要实现调度器; Generator算是一种带有状态的Callback,或者是对象化的Callback,它们也需要运行在Thread里面,要利用多CPU,需要实现调度器; 为什 ...
先总结一下。 线程是最容易编写的并发方式,操作系统也提供了最好的支持;协程可以做到更强的并发能力,但需要实现调度器;回调是开销最小的,它本来不是特别为并发来设计的,它是通用的异步化操作的实现模型。 注意线程和协程本身也是使用异步来模拟同步,线程由操作系统来模拟,协程由用户级调度器模拟。模拟的过程是:发起事件请求、挂起当前执行过程(线程或协程)、响应事件请求、恢复挂起的执行过程。回调没有这么复杂,你需要自己把连续的执行过程分解成多步操作。 线程就不讨论了,用起来比较简单;协程之前简单研究了一下,切换开销比线程有很大改进,但还是有点大,用作IO事件调度还可以,粒度更小的操作就显得开销过大了,想 ...
Coroutine切换成本相对还是比较高的,把一个并发程序改成Coroutine实现性能上可能有比较大的损失。Coroutine切换主要是大量寄存器压栈和弹栈,栈切换也会影响到cache。目前C/C++大量使用的是回调方式,比如win32窗口编程、libevent等 ...
前段时间公司网站出过两次事故,前台跑PHP的Apache进程大量死锁,造成服务器无负载但不能提供服务,不断重启服务也未能解决问题,但过几小时后自动恢复。这些系统已经稳定运行数月之久,虽然不断有升级但没有出现这类情况。 一周后第二次出现相同情况时公司组织人力进行了排查,没有发现问题。由于没有WEB机器登录权限,于是让运维同事做了这些操作来查找原因: 1、strace -p xxxx查看任意httpd进程,查看进程运行状态。如果没有阻塞在futex上,换一个进程再查看。 这一步一般可以查出很多原因,比如死循环,如果strace没有显示一个系统调用正在进行,一般是限入无终结条件的死循环,这种情况一 ...
简单比较了一下ucontext和Erlang的进程切换效率,在我的机器上ucontext每秒可以完成90万次切换,Erlang则要快得多,每秒可以完成412万次切换,这个性能比较和之前shootout上的测试相近。 效率差这么多是可以预见的,C的轻量级线程实现都是栈切换的,要完成寄存器保存和加载,只是不需要经过系统调度。相比之下其它语言的轻量级线程切换通常不是C栈切换,开销要小得多。 有这么大的差距是不是Erlang就有很大的性能优势呢?我觉得不是。Erlang为了保证实时性,把进程调度的粒度设置到函数调用这个级别上,复杂的应用中很容易导致过多的切换;而C实现则是由程序员自己找准时机来切换, ...
最近下决心和Erlang说再见了,想了很多,也用了一段时间,断断续续数落过几次Erlang的优缺点,看得不深,权当我是瞎说。简单整理一下: 优点:高并发、分布式、资源管理、高效率(和其它动态语言比较)、热升级、自动并 ...
前面给了个Io异步编程的例子,最后说“和Erlang比一比“,我指的是Erlang做类似的功能需要pmap。 为什么Io的List#map可以适应这种并行调用?本文简单分析一下。 通过阅读源码,首先可以确定的是map本身没有作任何特殊处理,所以重点放在"@"这个操作符上,它完成异步操作。 经过测试发现,方法如果是异步调用(应该说消息是异步发送,说方法调用感觉自然一些),如果不“使用”调用结果,是不会等待结果返回的。这里的“使用”并不是简单地赋给一个变量,而是真正使用这个变量,比如返回一个整数,简单地: a := foo @bar 并不会等待调用的结果,只有使用a ...
迫不及待地介绍这个特性,来看一下Io是如何在不改变调用过程的情况下让调用变成异步的。 先看一个同步调用: Slow := Object clone do( call := method(i, wait(i) "DONE" println i + 1 ) ) results := list(1,2,3) map(i, Slow clone call(i) ) results println 这个程序将花上6秒来完成。如果调用本身消耗CPU比较少,就可以并行来运行。上 ...
Io Language没有关键字,所以它的语法很简单: // 赋值 a := "hello world" // 取值 a // 方法调用: a println // 方法调用2: a split(" ") // 方法调用3: a slice(1, 3) // 方法调用在Io里面叫作message,和Ada, Ruby, Objective-C这类语言相似 // 操作符: 1 + 1 // 操作符本身也是函数: 1 + 1 // 等价于 1 getSlot("+")(1),函数 ...
Global site tag (gtag.js) - Google Analytics