摘要:数据副本强一致、全节点可写、存储全面降本,GaussDB(for Redis)重新定义游戏数据库,彻底修复一致性BUG。

本文分享自华为云社区《华为云GaussDB(for Redis)揭秘第24期:游戏一致性BUG怎么解》,作者:高斯Redis官方博客 。

关于游戏与一致性

最近在跟一些游戏客户交流,聊到了容易让人“踩坑”的数据一致性问题,常见BUG有“背包道具丢失”、“一个玩家同时加入两个公会”等等。这类问题往往藏得比较深,等到游戏上线后期才发现,会比较难解决。

其实,只要前期做好数据库选型和架构设计,一致性问题是可以避免的。本文将聚焦两大主要场景,对数据一致性问题进行详细剖析。

场景一:读写分离引起的数据不一致问题

在游戏行业,MySQL很多时候都是首选的“主数据库”。然而游戏业务也有很多高并发场景,当上千RPS的MySQL不够用时,为了提升吞吐,就可能会做读写分离、分库分表。

但如果需要更高吞吐能力,MySQL可能会无法满足,这时可以引入Redis,利用NoSQL的强扩展性,承载上万,甚至是数十万RPS。同样的,Redis也可以做读写分离。

1.读写分离引发的BUG

  • 背包道具丢失(MySQL做主数据库场景)

BUG描述:玩家在游戏地图A购买道具,随后立刻切换地图,进入游戏地图B,结果打开背包竟发现道具丢失。

根因分析:前一个地图的购买行为写入主节点,而新地图中打开背包时查询了从节点。由于主从同步有延时,导致没查到最新数据。

  • 关注好友后漏发Hi~(Redis做主数据库场景)

BUG描述:在某个游戏地图中遇到美女玩家,关注对方后,本应自动发送预定义招呼语,对方却迟迟没有收到。

根因分析:好友链这种业务很适合用Redis做主数据库(提供灵活的hash/set/zset)。但是社区版Redis天然弱一致,原理同上,由于脏读发生,读写分离必踩坑。

2. 如何解决?

做读写分离的初衷,其实还是对算力水平扩展有诉求,同时也是不想让那些“Slave”们闲置浪费(毕竟算力成本也是钱呐)。

其实,数据库不止MySQL一种,缓存也不止Redis一种。

华为云GaussDB(for Redis)作为企业级定位的KV数据库,已经在很多业务场景被用作 “主数据库”了,单实例存储TB级数据是家常便饭。

GaussDB(for Redis)可以根除读写分离的一致性问题,原因如下:

1)支持36个节点,全都可读可写(全员Master,算力别浪费)

2)数据强一致(无需主从分离,并发访问任一节点都无脏读)

3)单实例承载数百万QPS(高吞吐需求从来不是事)

很显然,高斯Redis完全可以满足“既要、又要”的业务诉求,让游戏远离读写分离之“坑”。

【有人可能会说,对不起,我是土豪,Slave就只用于高可用,我的业务不读它,这样总不会踩坑了吧?其实,隐患还是存在的!】

场景二:主从切换引起的数据不一致问题

请时刻注意,你使用的数据库,不论是MySQL还是Redis,他们都是高可用的。而高可用意味着,当主节点故障时,它们会发生主从切换。

1. 主从切换引发的BUG

BUG描述:暑假做活动,全服玩家参与抢购100件稀有装备(官方公告:每件都是全服仅有)。后来在公会PK时,持有“屠龙刀”的玩家A遇到了持有“屠龙刀”的玩家B……发生了“撞刀”。

根因分析:活动期间,业务使用了一套Redis主从做抢购,创建一个Redis队列存稀有装备。活动期间请求量高,Redis发生了主从切换。于是BUG就这样发生了:本来队列已经pop掉了“屠龙刀”,但是由于主从同步延迟,从节点顶上来后,其中队列内的“屠龙刀”此时还没有被pop掉!活动继续,于是随后两个玩家同时拥有了“屠龙刀”。

2. 如何解决?

开源Redis主从切换导致的此类BUG其实很常见,业务以为访问的数据是稳定的,但其实社区版Redis随时可能“突变”(主从切换)导致业务读到旧数据。

解决办法还是一样——做正确的数据库选型,使用华为云GaussDB(for Redis)。

为什么说GaussDB(for Redis)没有这类问题:

1)数据强一致存储,故障场景业务不会发生脏读

2)故障秒级恢复(社区版Redis启动慢,需加载全量数据,故障恢复慢)

3)存算分离架构,容忍N-1分片故障(社区版Redis只要故障1对分片,业务无法恢复)

使用高斯Redis,完全不用担心脏读发生。

结语

其实在很多业务场景,如果不希望出现脏读导致业务BUG,那么华为云的高斯Redis的确是最佳数据库选型。另外,高斯Redis自带了冷热数据交换能力,本身也是一个兼顾了性能与成本的降本方案,像是游戏公司常用的protobuf序列化数据,高斯Redis能实现500G到160G的数据压缩(案例数据),轻松节省70%存储空间。

高斯Redis既能为游戏业务保驾护航,又省心省力省钱,何乐而不为!

附录

  • 本文作者:华为云数据库GaussDB(for Redis)团队
  • 更多产品信息,欢迎访问官方博客:bbs.huaweicloud.com/blogs/248875

点击关注,第一时间了解华为云新鲜技术~

游戏开发常遇到数据一致性BUG,怎么解?的更多相关文章

  1. Android游戏开发之旅 View类详解

    Android游戏开发之旅 View类详解 自定义 View的常用方法: onFinishInflate() 当View中所有的子控件 均被映射成xml后触发 onMeasure(int, int) ...

  2. 【Unity游戏开发】记一次解决 LuaFunction has been disposed 的bug的过程

    一.引子 RT,本篇博客记录的是马三的一次解决 LuaFunction has been disposed 的bug的全过程,事情还要从马三的自研框架 ColaFrameWork 说起.最近,马三在业 ...

  3. 《Cocos2d-x游戏开发实战精解》学习笔记4--实战一个简单的钢琴

    上一节学习了使用Cocos2d-x播放音乐的方法,但是那种方法一般只适合于播放较大的音乐,而一般比较短小的音乐(如游戏中的打斗.按键音效等)则要通过playEffect来播放.本节使用该方法以及之前学 ...

  4. 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音

    <Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...

  5. 《Cocos2d-x游戏开发实战精解》学习笔记1--在Cocos2d中显示图像

    Cocos2d-x中的图像是通过精灵类来显示的.在Cocos2d-x中游戏中的每一个角色.怪物.道具都可以理解成是一个精灵,游戏背景作为一种特殊的单位将其理解成是一个精灵也没有什么不妥.在源文件本章目 ...

  6. 《Android游戏开发详解》一1.7 控制流程第1部分——if和else语句

    本节书摘来异步社区<Android游戏开发详解>一书中的第1章,第1.7节,译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社区"异步社区"公众号查看. 1.7 ...

  7. [Canvas前端游戏开发]——FlappyBird详解

    一直想自己做点小东西,直到最近看了本<HTML5游戏开发>,才了解游戏开发中的一点点入门知识. 本篇就针对学习的几个样例,自己动手实践,做了个FlappyBird,源码共享在度盘 :也可以 ...

  8. Canvas前端游戏开发——FlappyBird详解

    一直想自己做点小东西,直到最近看了本<HTML5游戏开发>,才了解游戏开发中的一点点入门知识. 本篇就针对学习的几个样例,自己动手实践,做了个FlappyBird,源码共享在度盘;也可以参 ...

  9. Unity3D游戏开发从零单排(四) - 制作一个iOS游戏

    提要 此篇是一个国外教程的翻译,尽管有点老,可是适合新手入门. 自己去写代码.debug,布置场景,能够收获到非常多.游戏邦上已经有前面两部分的译文,这里翻译的是游戏的最后一个部分. 欢迎回来 在第一 ...

随机推荐

  1. linux篇-linux mysql5.6.27源码安装和错误解决

    centos mysql5.6.27 1编译安装 先进入到文件放置的路径下 创建一个个文件 #mkdir–p /data/mysql/mysql #mkdir–p /data/mysql/mysqld ...

  2. 好客租房14-在jsx中使用javascript表达式的注意点

    注意点 单大括号中可以使用任意的表达式 jsx自身也是js表达式 注意:js中的对是一个例外 写在style样式中 //导入react     import React from "reac ...

  3. sqlserver 插入 更新 删除 语句中的 output子句

    官方文档镇楼: https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/ms177564(v=sql.100) 从 ...

  4. 第06组Alpha冲刺总结

    目录 1. 基本情况 2. 思考与总结 2.1. 设想和目标 2. 计划 3. 资源 4. 变更管理 5. 设计/实现 6. 测试/发布 7. 团队的角色,管理,合作 8. 总结 3. 敏捷开发 1. ...

  5. Java学习-第一部分-第一阶段-第二节:变量

    变量 变量介绍 为什么需要变量 变量是程序的基本组成单位 不论是使用哪种高级程序语言编写程序,变量都是其程序的基本组成单位,比如: //变量有三个基本要素(类型+名称+值) class Test{ p ...

  6. js 循环生成元素,并为元素添加click事件,结果只执行最后一个点击事件

    问题描述:有一个参数集合data,for循环为每一个参数生成一个dom元素,并附加onclick事件.生成之后发现点击事件里的参数全是data集合里的最后一个. 代码如下: var dom=$('#d ...

  7. 【python基础】第06回 运算符和流程控制 1

    本章内容概要 1.运算符 2.流程控制 本章内容详解 1.运算符 什么是运算符? 运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算.例如:2+3,其操作数是2和3,而运算符则是" ...

  8. Web思维导图实现的技术点分析(附完整源码)

    简介 思维导图是一种常见的表达发散性思维的有效工具,市面上有非常多的工具可以用来画思维导图,有免费的也有收费的,此外也有一些可以用来帮助快速实现的JavaScript类库,如:jsMind.KityM ...

  9. p_b_p_b 杂题选讲

    [ARC119F] AtCoder Express 3 [ARC117F] Gateau 考虑二分答案,对前缀和建差分约束 \(\text{check}\) ,但是用 \(\text{spfa}\) ...

  10. 步态识别《GaitSet: Regarding Gait as a Set for Cross-View Gait Recognition》2018 CVPR

    Motivation: 步态可被当作一种可用于识别的生物特征在刑侦或者安全场景发挥重要作用.但是现有的方法要么是使用步态模板(能量图与能量熵图等)导致时序信息丢失,要么是要求步态序列连续,导致灵活性差 ...