游戏服务器对缓存服务器和数据库的关系不一致数据是怎样处理的

缓存使用问题[数据库/ORM/服务器/HTTP] - 开源中国社区
当前访客身份:游客 [
当前位置:
小弟不才,在了解完缓存的一些知识后对缓存的使用问题产生了一些疑问,该如何合理的使用缓存?
我现在知道的缓存有:数据库查询缓存(如Mysql查询缓存) - ORM框架缓存(如Hibernate的查询缓存/一二级缓存) - 服务器缓存(如memcached/redis) - HTTP缓存加速器或者服务器(如varnish/nginx)等。
他们都是一级一级下去的,各自都能理解,但是关于结合使用的问题还是有些不是很清楚。
1、数据库查询缓存和ORM框架缓存之间查找顺序是:ORM查询缓存 - 数据库查询缓存 - 数据库实体表吧?那么对于单应用服务/单数据库服务这两个查询缓存是不是有点冗余。
2、ORM的二级缓存有没有必要使用服务器缓存,我感觉本地缓存(ehcache)就够了,去memcached(远程)去拿一来可能没有本地快,二来感觉memcached之类的还是老老实实存些字典项权限啊什么之类的信息。(这点真是恕我愚见。)
3、各位平时的缓存策略是怎么样的?(这个才是重点。)
上述理解大言不惭如有偏颇请谅解~
共有1个答案
<span class="a_vote_num" id="a_vote_num_
基本多读少写的场景下为了提高响应必然需要缓存,而每层缓存只解决该层的响应问题,不能因为其他层有缓存就觉得变成冗余了。毕竟请求从应用层往数据层走的过程中,业务逻辑实际上是在逐步细化的,每个缓存对应的逻辑单元大小都不同,所以每层缓存解决的响应问题层面也不同。
而至于orm的二级缓存问题,我的看法是和你的业务逻辑与服务器部署有关,如果是单机前端服务器,而且服务器配置够好不会和业务逻辑争抢系统资源的话,使用本地缓存也可以。但是如果多机的话,还是得使用服务器缓存,毕竟缓存数据更新时需要在整个业务环境中更新,而本地缓存只能更新目前响应的这台服务器的缓存,其他服务器的本地缓存不更新的话会造成数据不一致和脏数据。
缓存策略就是多读少写且请求量大的数据都得加缓存!
更多开发者职位上
有什么技术问题吗?
65535的其它问题
类似的话题& & & 在页游服务器这块很早之前一直没有认真考虑过,大部分是之前搭建好的,我只需要按照他原来的设计继续码代码就好了。
& & &可是这次服务器重构的过程中,还是遇到了很多始料不及的问题。那么就按照踩过的坑,去一个个讲讲分析分析。
& & &1:起初mysql的方案
& &起初的设计方案是这样,用一个RolePlayer 去做玩家数据的缓存,所有玩家的数据更新到RolePlayer中,定时十秒中更新到数据库。RolePlayer大概是这样一个设计
& & & class RolePlayer&
& & &   public int roleId;
& & & & & & public String packI
& & & & & & public String equipI
& & & & & & public String taskI
& & & & & & .....
& & & 每十秒钟对所有在线的RolePlayer做一个批处理的更新,用的jdbc,对于玩家的流水也是如此,只是更多的是拼凑的字符串,比如这样insert into onlineserials(roleid,rolename,oltime) values (1212929,"wanjia1",12222),(1212929,"wanjia1",12222),(1212929,"wanjia1",19,"wanjia1",12222),(1212929,"wanjia1",12222) 。对于流水的处理还算比较谨慎,当流水条目到达5k之后 才做一次插入。我想这大概是一个页游服务器对mysql的通用设计,可是无奈总是出现内存泄露,用工具查看,基本是 string中的char占到了内存的40%,无论我使用什么回收方式都无效。 &当然我依然觉得这是一个很好的设计,只是我自己在使用上还是欠水准。
  2:mongo的数据库方案
  后来调整数据库为mongo的,大家不要惊讶,我用的是json格式存储的数据库,这样兼容mysql和mongo,所以调整起来比较容易。mongo使用起来就比较简单了,对于这种nosql 内存数据库,使用起来就方便不少,无论是更新还是查询。基本的设计就是当玩家的数据改变的时候,就更新到数据库,当然是通过一条消息异步到数据库线程去做更新,对于流水的记录也是同样的道理。只是mongo 是一个内存怪兽,对于内存的贪婪,想必用过的人都清楚,对于mongo对于内存的管理大家可以百度下,有很多这样的文章,在这里就不详细解释。我起初也是毫无办法,甚至去读外文资料。找到我们之前的运维,他们也说并没有对mongo做太多的设置,只是用了一个内存25g+raid10硬盘 去专门部署mongo数据库,ssd确实太贵用不起。在网上微博上搜集了一些资料也分享给大家,虽然并不能完全控制,但是也不失为一个很好的办法。
  3:控制mongo的内存
   &1: 调整linux内核的内存管理方式:&shell& sysctl -w vm.drop_caches=1
& & & &2:利用mongo提供的方式去回收整理内存:使用时会影响mongo的效率
& & & & & & & &&mongo&
      &mongo&db.repairDatabase();
& & & &3:主动清理linux的cache内存:&echo 3 & /proc/sys/vm/drop_caches
     &说明,释放前最好sync一下,防止丢数据。
&可以用一个将上面的命令定时跑 去释放mongo的内存。
  4:控制mongo内存最终的方案
  在翻看《mongo实战》这本书的时候发现了capped collection的用法。capped collections有如下优点:
& & & & & & & & &1: 固定大小集合,如此便防止了内存无限扩张。
& & & & & & & & &2: 以LRU(Least Recently Used)规则和插入顺序进行age-out(老化移除) 处理,自动维护集合中的插入顺序。 & & &
& & & 初看会以为 固定大小是一个很大的限制,但其实对于也有来说已经足够,现在的页游导入用户 基本在万级别。 老化移除防止了内存的无限矿长,对于流水,我们大部分只是要最近的流水来查找问题,对于一个月以前的流水,我想没人会关心。 & & & &
& & & 另外补充,调整ulimit 并不能控制住mongo对于内存的使用。
& & & 如有误,望批评!
阅读(...) 评论()如何解决数据库崩溃_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
如何解决数据库崩溃
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢关于socket发送和接收缓存区大小的设置和如何保证服务端接收到完整的数据的问题。-c/c++-电脑编程网关于socket发送和接收缓存区大小的设置和如何保证服务端接收到完整的数据的问题。作者:Going1981 和相关&&项目需要一个手机向电脑上传文件的小程序,我以前没做过socket相关的东西,在网上找了部分代码再加上自己的理解后终于把程序写出来了,但在测试中发现了一些问题,头脑已经混乱了,只好来求助大家了!目前电脑跟电脑间传输文件没有发现什么问题,就是手机往电脑传输时电脑接收的文件总是不正确,比如传输图片时,接收的图片会出现错位、色彩失真,传输音乐时也会失真。经过测试发现调整接收缓存区的大小对接收的文件的完整性影响很大,越大的缓存区(大于1024)失真越利害,当接收缓存区设为256时接收的文件基本就正常了。但我看大家一般都是设1024的接收缓存区,而且设256是不是效率非常低下?请教大家:1、在socket传输中设置缓存区的原则是什么呢?2、socket传输时怎么保证数据完整性和正确性?另外还有个问题也一并请教了:我的项目大概50个左右手机终端,平均每天每个手机传输20-30M文件到,上传的时间不固定,并发量应该不会超过10。在这样的情况下,应该采用什么样的监听策略呢?------回答---------------其他回答(20分)---------socket没接触过 帮你顶 希望能得到满意答案
------其他回答(20分)---------缓冲区要视你传输文件的大小而定
太大又太占内存
& 保证完整性方面
就是传完后的一个检验吧
或者哪个数据块出错了就重传哪个数据块
这就是具体你想怎么实现的问题了。
------其他回答(20分)---------1、在socket传输中设置缓存区的原则是什么呢?2、socket传输时怎么保证数据完整性和正确性?1。手机上不晓得是多少,PC机之间使用默认的就可以了。2。SOCKET TCP协议是基于流传输的,所以要处理边界问题,发送数据前,先发送数据长度,接收方先解析出长度,再接收数据。服务器监听使用异步监听就可以了。
------其他回答(20分)---------这是一个完整的,异步socket处理的源代码,包括了说明,实现了等处理,你可以参考一下!/KB/IP/AsyncSocketServerandClien.x有不理解的,可以交流讨论。
------其他回答(30分)---------呵呵,用几秒钟就会发现你的很多问题。说两个比较明显的吧:1. state.data.AddRange(state.buffer); 这一句显然是错的,state.buffer中只有前bytesRead 个字节是接收来的,你怎能把整个buffer丢进去?!2. 我看到你既有异步操作,又有循环、信号来那个阻塞,这是很浪费线程资源的做法。真正的异步操作程序不会出现循环语句,也不会用到信号量阻塞。不过其实解决1.你就能够准确接收文件了。2.是针对整体效率和服务器资源的申请和释放而言的。唉,类似通信问题,msdn上尚且胡写“范例”程序,csdn上你能指望什么呢?
------其他回答(5分)---------Compast Framework没有对FTP的支持------其他回答(5分)---------没接触过,帮你顶!------其他回答(5分)---------learn------其他回答(5分)---------学习了,留个记号。顶。可以结贴了。呵呵------其他回答(20分)---------引用 8 楼 sp1234 的回复:呵呵,用几秒钟就会发现你的很多问题。说两个比较明显的吧:1. state.data.AddRange(state.buffer); 这一句显然是错的,state.buffer中只有前bytesRead 个字节是接收来的,你怎能把整个buffer丢进去?!2. 我看到你既有异步操作,又有循环、信号来那个阻塞,这是很浪费线程资源的做法。真正的异步操作程序不会出现循环语句,也不会用到信号……这位兄弟真有意思. 不知道是否真的SP行业的. 如果是的话咱们还算同行了.SP行业的程序员一般都是写 socket 客户端,巨大压力的服务端,也基本没有应用场景.就socket编程而已,其他很多语言就2个方式: 阻塞,非阻塞(select).而C#好像很独特,居然有3个模式(我也是道听途说):阻塞,非阻塞,异步虽然我一直对C#的第3种模式很好奇但一直也没机会去研究.并且C# socket基本我也只接触过客户端.所以你说[真正的异步操作程序不会出现循环语句]我虽然表示怀疑,但是还是不争论了,因为我对C# socket服务器 端没太多发言权.但就传统的socket来讲, 也好, c++也好都是2个模式:1,阻塞+线程池2,非阻塞select 编程.而第2个 模式恰恰与你的观点相驳. 因为这个模式 就是以while循环来进行循环select的. 而这个模式可以说是socket server编程的标准了.不知道C#是否真的有更合理的方式让程序员免去写while来操作socket了 但我想就算免去写while了 基本原理也不太可能变化.呵呵
------其他回答(5分)---------beginSend是异步用send试试&listener.Accept------其他回答(5分)---------期待中...------回答---------------其他回答(20分)---------
socket没接触过 帮你顶 希望能得到满意答案
------其他回答(20分)---------
缓冲区要视你传输文件的大小而定
太大又太占内存
& 保证完整性方面
就是传完后的一个检验吧
或者哪个数据块出错了就重传哪个数据块
这就是具体你想怎么实现的问题了。
------其他回答(20分)---------
1、在socket传输中设置缓存区的原则是什么呢?2、socket传输时怎么保证数据完整性和正确性?1。手机上不晓得是多少,PC机之间使用默认的就可以了。2。SOCKET TCP协议是基于流传输的,所以要处理边界问题,发送数据前,先发送数据长度,接收方先解析出长度,再接收数据。服务器监听使用异步监听就可以了。
------其他回答(20分)---------
这是一个完整的,异步socket处理的源代码,包括了说明,实现了等处理,你可以参考一下!/KB/IP/AsyncSocketServerandClien.x有不理解的,可以交流讨论。
------其他回答(30分)---------
呵呵,用几秒钟就会发现你的很多问题。说两个比较明显的吧:1. state.data.AddRange(state.buffer); 这一句显然是错的,state.buffer中只有前bytesRead 个字节是接收来的,你怎能把整个buffer丢进去?!2. 我看到你既有异步操作,又有循环、信号来那个阻塞,这是很浪费线程资源的做法。真正的异步操作程序不会出现循环语句,也不会用到信号量阻塞。不过其实解决1.你就能够准确接收文件了。2.是针对整体效率和服务器资源的申请和释放而言的。唉,类似通信问题,msdn上尚且胡写“范例”程序,csdn上你能指望什么呢?
------其他回答(5分)---------Compast Framework没有对FTP的支持------其他回答(5分)---------没接触过,帮你顶!------其他回答(5分)---------learn------其他回答(5分)---------学习了,留个记号。顶。可以结贴了。呵呵------其他回答(20分)---------
引用 8 楼 sp1234 的回复:呵呵,用几秒钟就会发现你的很多问题。说两个比较明显的吧:1. state.data.AddRange(state.buffer); 这一句显然是错的,state.buffer中只有前bytesRead 个字节是接收来的,你怎能把整个buffer丢进去?!2. 我看到你既有异步操作,又有循环、信号来那个阻塞,这是很浪费线程资源的做法。真正的异步操作程序不会出现循环语句,也不会用到信号……这位兄弟真有意思. 不知道是否真的SP行业的. 如果是的话咱们还算同行了.SP行业的程序员一般都是写 socket 客户端,巨大压力的服务端,也基本没有应用场景.就socket编程而已,其他很多语言就2个方式: 阻塞,非阻塞(select).而C#好像很独特,居然有3个模式(我也是道听途说):阻塞,非阻塞,异步虽然我一直对C#的第3种模式很好奇但一直也没机会去研究.并且C# socket基本我也只接触过客户端.所以你说[真正的异步操作程序不会出现循环语句]我虽然表示怀疑,但是还是不争论了,因为我对C# socket服务器 端没太多发言权.但就传统的socket来讲, 也好, c++也好都是2个模式:1,阻塞+线程池2,非阻塞select 编程.而第2个 模式恰恰与你的观点相驳. 因为这个模式 就是以while循环来进行循环select的. 而这个模式可以说是socket server编程的标准了.不知道C#是否真的有更合理的方式让程序员免去写while来操作socket了 但我想就算免去写while了 基本原理也不太可能变化.呵呵
------其他回答(5分)---------beginSend是异步用send试试 &listener.Accept------其他回答(5分)---------期待中...相关资料:|||||||关于socket发送和接收缓存区大小的设置和如何保证服务端接收到完整的数据的问题。来源网络,如有侵权请告知,即处理!编程Tags:                &                    }

我要回帖

更多关于 缓存和数据库一致性 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信