博文

目前显示的是 八月, 2011的博文

mina & protocol buffers

今天拿mina和protocol buffers写了一个简单的TCP Server。http://code.google.com/p/uniqname/一款网络游戏通常会分为很多组服务器,各组服务器之间数据基本是不通的,而且经常要合并。拿魔兽世界来说,合服的时候总是2合一,一个主服,一个副服。副服的一个角色名如果和主服上的某个角色重复,那么这个人就会被迫改名,否则不能进入游戏。同时,好友列表、帮派等社交关系也会被清空。(3.x时代的魔兽世界)那么一个好一点的办法就是,从一开始就为服务器划好区,每个区有一个唯一名服务器,玩家创建角色的时候就做好重名检查,让同一个区(而不仅仅是本服)的角色名不重复。那么合服的时候,玩家感受会好一点。唯一名服务器最重要的一个接口就是allocate(String name),判断一个名字是否已被占用,否则就占了它。实现起来很简单,但是我想写一套新的RPC框架,而不是用现有的比如JMX、RMI、WebService之类的,于是就想把mina和protocol buffers配合起来。用mina做IO管理,用protocol buffers定义message、service、method。网上虽然有一个这样的实现,但是它用的是短连接,每次请求都会产生一个新的TCP连接,而我想要长连接,因为短链接需要像HTTP那样自己在用户层增加字段来维护session。我觉得所有的RPC实现,最大的麻烦就是如何处理out-of-band信息,比如传输层超时、比如对方抛出了一异常、如何获取peer address,如何为这些东西定义好恰当的接口,是很头疼的事情。google protocol buffers在每个函数都加了一个Controller对象,但是并没有文档描述它设计这个的动机是什么。这个Controller到底是每个Service一个,还是每个Server一个,还是每次收到请求的时候都创建一个新的?把它当Session用可不可以?貌似google还是建议你不要用,如果有这方面的需求,那么就给protoc写plugin吧。回来的路上我又在想,传统的模式是 Client-> GameServer-> Uniqname Server。往往,直接与Client交互的Server只有一个,而它经常是在做请求代理。但是如果引入 Kerberos 这…

2011-08-10

今天一行代码都没写。昨天到了一台服务器,DELL T310。今天开始折腾它。先装了一个fedora 15,然后是subversion、openldap、samba。openldap的官方手册和fedora系统下的这个严重对不上,在网上搜种种教程,凡是含有slapd.conf的统统滤掉。fedora的手册上找到这么一句话:"Note that OpenLDAP no longer reads its configuration from the /etc/openldap/slapd.conf file." fedora下要去修改/etc/openldap/slapd.d/cn=config/olcDatabase={1}bdb.ldif 。samba的官方手册着实让我震惊了,巨长无比,但是想查一些简单问题吧,比如在standalone模式下如何把passdb换成openldap,木有写。不过也难怪,Windows AD本来就是超级超级复杂的东西,如果把smbd当windows AD用,那非得好几本书来写才行。我想把subversion和samba的身份认证都统一成ldap,结果只完成了前者。我想让用户自己能通过ldap协议修改密码,比如这样ldappasswd -x -D "uid=scm,ou=users,dc=www,dc=sunchangming,dc=com" -W -S "uid=scm,ou=users,dc=www,dc=sunchangming,dc=com"但是它报告说Result: Insufficient access (50)因为默认情况下openldap不让用户自己修改密码,以前完美的ldap server也是如此,然后我去找panpan,看他很快速的修改了一个配置,就好了。这次我也想改,但是一头抓瞎。我觉得应该是得通过修改/etc/openldap/slapd.d/cn=config/olcDatabase={1}bdb.ldif这个文件增加授权,比如
olcAccess: to attrs=userPassword by self write by anonymous auth by dn.base="cn=Manager,dc=www,dc=sunchangming…

SSD,你真的需要吗?

qingran写了一篇SSD的blog,http://www.qingran.net/2011/07/%e5%a6%82%e4%bd%95%e5%86%99%e4%b8%80%e4%b8%aa%e4%b8%bassd%e4%bc%98%e5%8c%96%e7%9a%84%e6%95%b0%e6%8d%ae%e5%ba%93%ef%bc%9f/ 。我早从他那里听说了很多关于SSD的神奇传说,但是我一直想不通。数据库的IO,可分为读操作和写操作。如果硬盘读的慢,那就增加内存,提高cache命中率。比如之前,我们的数据库cache命中率在99.99%以上,那么硬盘是随机读还是顺序读什么的根本不重要,除非对数据库的响应延迟有苛刻要求。至于写操作,大部分数据库的cache策略都是write behind而不是write through,写慢点也无所谓。事务在提交的时候,对log buffer有3种处理策略:立即写入硬盘并fsync、立即写硬盘、暂时不管。前两者的区别在于,是否容忍OS崩溃这样的事件。反正咱又不是做银行的事务系统,干嘛要求那么苛刻?因机器意外断电而丢失最近一分钟内的数据,大多数产品经理都能接受。而后两者的效率相差很小。所以即便每次事务提交都写硬盘,即便硬盘的写入延迟很高,只要能放心的相信操作系统帮我临时保管数据,那么这一切都不是问题。所以当我看很多人用SSD来存放InnoDB的log file的时候,我总想问,你真的需要吗?如果用SSD是为了提高读取速度,那先把内存槽插满吧,加到128G再说,或者想想,为什么数据访问没有呈现一定的本地性?我拿perl写了简单的for循环,连接本地的mysql,随机更新一个3万行记录的表的某一行,测试结果是QPS总是停留在5000左右(单线程、长连接),此时mysql的CPU使用率到90%多了。所以我在想此时的瓶颈究竟在哪,不知道下一步该怎么做更细致的性能分析。我发现hibernate的二级缓存其实是一个很有意思的东西。在数据库和应用层之间做一个本地cache,每次查询先找它要,查不到再去数据库要。即便数据库查询代价极小,这么做也很有意思。因为数据在数据库内都是以二进制流或者column的方式存储的,把它映射到object上,必然有一个序列化/反序列化的过程。对于一个TPS很高的应用来说,必须得像这样做row-level cac…