游戏开发到后期,随之而来的是各种性能测试调优。前两天看两年前写的数据库服务器,那叫一个囧,当初设计是单线程的,也就是所有的数据库操作请求放入一个队列中,逐个取出来做数据库查询操作。虽然mysql 的性能很赞,但要是这样游戏有个几万人在线,数据库服务器肯定吃不消。得益于innodb 的行锁支持,很多数据库的请求都是可以被并行处理的,比如两个角色A 、B 同时登录,进行登录验证并且获取角色列表请求,角色A 和B 数据是完全不相干的,所有可以并行处理。
后期数据库改动可是个大工程,不过为了性能还是忍了,狂改了一个星期,才把所有的数据库操作搞定。
数据库操作优化从两个方面入手:
1. 多个工作线程,并行处理 脏数据
2. 数据库操作API 用预处理方式(mysql_stmt_* 系列函数)
这里多个线程并行工作不用多说,用预处理方式操作数据库,在同一个连接上再执行相同的操作时,mysql 省去了解析sql 语句的工作,直接传入参数执行查询,对于大量复杂的相同查询,用预处理方式节约不少。
接下来讨论一下服务器的工作模式( 线程模型) 。考虑一下这样一种情况,同一个角色发送了两个请求,并且都是针对同一条数据操作,第一个写第二个读。那么为了保证数据的正确性,两个请求必须保证顺序执行。要是使用简单的生产者- 消费者模型,来一个请求,只要有空闲的工作线程就被处理,这种方式的话两个请求的执行顺序是不能保证的。这样我们必须保证同一个角色的数据请求会被顺序执行。
为了保证这一点,我们就得为每个请求加一个标记,比如角色ID ,这里称这个标记为阻塞项。用阻塞项让请求按照我们的期望顺序执行,