摘要:数据副本强一致、全节点可写、存储全面降本,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. CefSharp 白屏问题

    原文 现象 我正在使用 cefsharp + winform 建立一个桌面程序用于显示网页.使用过程中程序会突然白屏,经过观察发现,在网页显示GIF动图时,浏览器子程序会突然占用较高内存(从80M上升 ...

  2. socket套接字补充、操作系统发展史、进程

    目录 socket套接字之UDP协议 操作系统的发展史 手工操作 批处理系统 联机批处理系统 脱机批处理系统 多道技术 进程理论 并发与并行 同步与异步 阻塞与非阻塞 同步异步与阻塞非阻塞总结 soc ...

  3. 前端2CSS2

    内容概要 伪元素选择器 选择器优先级 字体样式 文字属性 背景属性 display属性 边框属性 盒子模型 浮动(重要) 解决浮动造成的影响 内容详情 伪元素选择器 """ ...

  4. ICDAR2013

    参考:https://www.cnblogs.com/dmyu/p/6483357.html以及博主相关文章等.

  5. 深度学习与计算机视觉教程(15) | 视觉模型可视化与可解释性(CV通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  6. php 图片转换二进制数

    $image = "1.jpg"; //图片地址 $fp = fopen($image, 'rb'); $content = fread($fp, filesize($image) ...

  7. 【Redis】quicklist

    Redis List 在Redis3.2版之前,Redis使用压缩列表和双向链表作为List的底层实现.当元素个数比较少并且元素长度比较小时,Redis使用压缩列表实现,否则Redis使用双向链表实现 ...

  8. Vscode标题栏出现【不受支持】提示的完美解决方案

    安装Fix VSCode Checksums code --install-extension lehni.vscode-fix-checksums 打开命令面板,快捷键 Ctrl + Shift + ...

  9. SAP BDC 调用中 金额格式转换

    在BDC调用中,由于用户设置不同,导致金额.日期等字段的输入格式不正确.此处给出 自创 金额转换FM 并配有 调用方式. function zgm_conver_cuur. *"------ ...

  10. python这不是有手就行?——python音频处理基础知识

    大家应该都知道声音的基础吧? 啊不知道当我没说吧~~~ 1.声音的基础 2.python读取.wav音频 Python学习交流Q群:660193417#### import wave import s ...