主程的晋升攻略(9):数据层的演进(下)

缓存为什么能提高性能?

为什么memcached的性能比mysql高?

首要因素是memcached的数据都是位于内存中,mysql的数据可能是位于磁盘里。从IO速度来说,内存IO比磁盘IO会快几个数量级,memcached也就比mysql性能更高。架构和性能优化做到后面,会发现最终限制性能的是硬件瓶颈。例如nginx做静态webserver时,出口流量往往能达到网卡的最大值或出口带宽的最大值。mysql是个性能还不错的db,但它的数据持久化在磁盘上,自然就受限于磁盘IO速度。

mysql也是有缓存的,但大多数场景下觉得还是不够用,这就涉及到次要因素——针对具体业务特征做优化。mysql支持完全的增删查改SQL操作,还得支持where条件组合,这种复杂性让mysql的缓存机制有较大挑战,不像memcached这种key-value类型的操作一定是点查询,所以mysql的缓存机制不如memcached那么简单有效。总结一点就是,性能、通用性、成本三者难以同时满足。在成本一定的情况下,专用的高效,通用的低效,ttserver/redis/mangodb也都符合这个原则。如何同时满足性能和通用性呢?那自然就是提高成本,最简单的方案是mysql+固态硬盘。

针对具体业务特征做优化,有很多我们耳熟能详的其他表述方法:因地制宜、因时制宜、具体问题具体分析、特例化等等。它确实是我们适用于人生、事业、技术的一个原则,是个好东西。经验多的优势就是能因地制宜、因时制宜的去分析解决问题。出现问题后,我们一般会先扛住再优化,必要时会拿空间换时间,或者拿时间换空间。

“空间换时间”看起来有点高深,其实只是个包装,举个例子就明白了。在《数据层的演进(上)》中,当访问量增加时,我们使用更多的机器横向扩容,性能得以提升,这个就是拿更多的机器(空间)来换用户更快的访问速度(时间)。

SNS查询

随着社交网络的普及,查询好友动态的需求更常见了。这个功能怎么实现呢?最简单粗暴的做法是先查询我的好友有哪些,然后再依次查询好友的动态,接着把这些好友动态聚合起来按时间排序,最后存入缓存中备用。上流的做法是,开发一个专用的server来实现这个功能,对外只用提供一个简单的接口。这个server内部还会把“依次查询好友的动态”变成“并行查询好友的动态”,最后再聚合,这样能提高速度,有点MapReduce的感觉。

数据一致性问题

业务server如果有多个(横向扩容),并且使用memcached这种公用缓存,那么需要处理好数据一致性问题。如果A和B两个业务server“同时”都从memcached缓存里读取了player信息,修改后用set方式写回到缓存时,那么先做的修改会被后做的修改覆盖掉,因为set方式是直接覆盖,不检查其他内容。为解决这个问题,可以采用cas方式更新缓存。

cas方式的思路是这样的,读数据时会获得数据的seq,cas更新数据时,先检查cas里提交的seq和缓存里的seq是否一致,一致才会更新数据并把seq+1。上述A和B读数据得到相同的seq,前一个cas更新成功后seq会变,后一个cas就会失败。这时需要业务server自行处理好cas更新失败的情况。

但这个又会衍生另一个问题,如果业务server的某个操作需要有5次数据更新操作,假如最后的cas操作可能失败,那么前面4次数据更新操作就麻烦了,是回滚,还是把最后的cas再操作一次,或者把这个失败记录在案就不管了?不管是哪种都有麻烦,不够完美,需要按业务实际的情况来做分析。

业务server内部缓存

为了避免上述数据一致性问题,在游戏后台设计中,还有一种做法是由gamesvr自己在内部管理缓存。这种做法的好处是缓存专用,不用考虑其他gamesvr修改缓存导致的数据不一致性问题。需要注意的问题是,数据只能在一个gamesvr里访问,如果需要访问其他gamesvr管理的数据,就通过proxysvr来中转请求。对于现在分区分服模式的游戏,只要没有太重的逻辑计算,用C++开发的gamesvr完全能一个server进程搞定一个区8000人同时在线(现实中一个区的同时在线也很难达到8000)。这样就是在gamesvr里搞定所有事情,不考虑互斥,不考虑数据一致性。

备份策略

线上业务如果没做数据备份,皮鞭滴蜡的惩罚都是轻的。重要数据采用每天全量备份+binlog增量备份+slave实时同步。这些都是常见技术方案,不啰嗦了。

时间: 2024-10-25 08:05:56

主程的晋升攻略(9):数据层的演进(下)的相关文章

主程的晋升攻略(7):服务器模型谈

在上一篇<主程的晋升攻略(6):CGI和FastCGI>中,讲到Web服务器和CGI/FastCGI能动态输出内容,从而提供更强大的业务处理能力.Web服务器这种架构,我称之为Web模式,与之相对的是Svr模式.Web模式和Svr模式是互联网项目的后台最常见的两种模式.先介绍几个概念. 同步通讯 vs 异步通讯 同步通讯是指在一个连接中,一个请求的应答没回来前,不能发送下一个请求,整个通讯过程是请求1-应答1-请求2-应答2--这种.异步通讯与同步通讯相反,在一个连接中,可以随意发送请求,而且

主程的晋升攻略(8):数据层的演进(上)

我们用一个做手游的故事来聊聊数据层不断优化提升的演进过程. 10:简单设计 有一天,老板突然说做个山寨版的糖果传奇手游,你接到任务后,分析出游戏的交互频率不大,都是点查询,用mysql能简单搞定.对游戏来说,你非常少有机会用orcale这样的上流货.mysql是物美价廉的选择.建个表,设好主键和索引.你轻松搞定数据库设计,满意的泡了杯茶边喝边写程序. 这里说的"点查询",是指基于指定主键的查询,比如查询指定用户的信息,由于是基于指定主键.查询结果有限且较少.点查询的效率很高. 还有一种

Axure RP使用攻略--带遮罩层的弹出框(9)

实现目标: 1.   点击按钮弹出带遮罩层的对话框: 2.   页面上下左右滚动时,弹出的对话框水平和垂直始终居中. 实现步骤如下: 1. 拖入编辑区2个矩形,并点右键-转换-转换为动态面板: 2. 双击其中一个动态面板设置标签为"遮罩层"(看个人喜好随便命名),并双击状态1进入编辑: 3. 点击状态1里面的矩形,设置大小与网站页面大小相同,以便完全遮盖:然后,设置矩形边框为"无":最后设置填充色的透明度为50%(看个人喜好),并选择填充色为灰色(看个人喜好): 4

【黄山-宏村攻略】

眼看着就要大四各自出去实习了,之后一宿舍聚在一起的机会就少之又少了,然后就趁着五一,拼一下假期,五天游玩 黄山 ,自己做的攻略发出来跟网友分享下. 因为还是在校学生,所以奔着  安全第一,节省第二,欢乐第三的原则.                                                                                                   103宿舍五一出行黄山攻略 福州北站2016.4.27下午16.14出发历史2.5小时抵

深度学习在携程攻略社区的应用

编者:本文来自携程攻略社区开发总监李健在携程技术中心主办的深度学习Meetup中的主题演讲,介绍了深度学习在攻略社区领域的主要应用.关注携程技术微信公号ctriptech,可获知更多技术分享信息. 携程攻略社区是携程旗下的旅游攻略类社区,致力于为旅行者提供出行指南和资讯服务.依托携程2.5亿用户总量,社区日活跃用户超过500万,并汇集3000万条真实用户的旅行和酒店点评,并有40万篇旅行游记,2000位知名旅行达人.面对数据库中浩如烟海的信息,我们如何能去其糟粕,留其精华? 攻略社区的主要需求

【携程攻略】千岛湖骑行-其他

[携程攻略]千岛湖骑行-其他 ? 千岛湖绿道骑行,千岛湖沿湖建有骑行车道,可以边骑行边欣赏千岛湖美景.骑行俱乐部20元一小时.千岛湖镇上就近安排车辆.咨询电话13777367764.微信号:yujian20060222

R语言教程:写给高级入门者的数据打理攻略

http://developer.51cto.com/art/201312/423612_all.htm 原文地址 如果大家还未完全熟悉R语言.甚至不能轻松利用它实现最基本的处理任务,我建议各位先查阅其它指导文章.帮助自己积累对R语言的认识.但如果大家已经拥有一定的背景知识,希望能够进一步提升自己的开发技能——或者单纯只是想看看R语言如何完成文章中罗列的四项任务——那么请跟着我继续阅读. 学习如何添加column.计算总和.对结果排序以及数据改造. 强大的能力在带来责任之外,也给我们增添了恼人的

redis大型攻略!

redis大型攻略 一:redis的简介.下载和安装 二:redis主从 三:redis在线升级 四:redis多实例 五:redis常见的操作 六:reids配置详解 实验环境:CentOS-6.5-x86_64   redis-2.8.9.tar.gz 一:redis的简介.下载和安装 Redis是一个key-valu存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集

Windows Socket五种I/O模型——代码全攻略(转)

Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权.这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误.但功能强大.为了解决这个问题,提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种: Windows Socket五种I/O模型——代码全攻