KBEngine官方论坛

 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 配置 开服
查看: 440|回复: 55

PY_DICT数据存盘

[复制链接]

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
发表于 2019-1-10 18:14:05 | 显示全部楼层 |阅读模式
我发现用PY_DICT这个类型作为数据库字段类型会忽略<Default>{"1":2,"2":3}</Default>这种默认值,并且用blob存储

问题一:那能否赋默认值呢?

问题二:数据存盘策略是什么呢?是能监听到这个dict这个数据的变化,每变化一次,就序列化发给dbmgr进程一次吗?如果是这样那一次修改10个值岂不是要给dbmgr发10次该dict序列化后的值,数据库在对应时间写10次?
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-10 18:37:00 | 显示全部楼层
数据库存储默认值后面会完善。

只能存blob, 他是python对象
QQ:3603661
3603661@qq.com
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-10 18:37:44 | 显示全部楼层
你不调用存盘就等定时整体存盘, 不会你一改就存
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-1-10 18:55:36 | 显示全部楼层
本帖最后由 CC2012520 于 2019-1-10 19:05 编辑
柯标 发表于 2019-1-10 18:37
你不调用存盘就等定时整体存盘, 不会你一改就存

存盘策略是啥呢?是每到<archivePeriod> 300 </archivePeriod>设定的时间间隔,就把需要存数据库的所有属性序列化发给dbmgr存盘吗?
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-10 19:54:12 | 显示全部楼层
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-1-11 09:48:10 | 显示全部楼层

存盘数据有做判断吗?比如有些entity的需要持久化的属性都没变过,这样就没必要存盘,不然如果内存几万个entity,存一次盘太耗了吧?

如果使用自定义数据结构,然后在Account中放入该结构的list存盘,会新建一个表来存,这样的话,如果list中有300个数据对象,只有一个发生了变化,是把这300个都存一次,还是只存这个变化了的呢?
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-11 10:13:52 | 显示全部楼层
几万个entity不会一次性存, 会分批到每个时间片存。
list不要放太多内容, 这块要准备优化。
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-1-11 10:21:26 | 显示全部楼层
本帖最后由 CC2012520 于 2019-1-11 10:35 编辑
柯标 发表于 2019-1-11 10:13
几万个entity不会一次性存, 会分批到每个时间片存。
list不要放太多内容, 这块要准备优化。 ...

希望entity能做存盘属性是否更改的判断,这样能减少很多不必要的存盘,比如加载对方离线数据,客户端下线Account数据在内存中暂留一段时间,这种需求往往会产生很多不会改变的entity,而数据库瓶颈问题还是挺让人担心的


很期待list的优化,比如物品等都是1对N的模式,把物品单独做成entity那内存entity要爆炸了,做成list如果每条都存盘,那数据库很容易产生瓶颈,一个游戏上千种物品还是有可能的,加上有些需要平铺那就不敢想了
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-11 10:39:18 | 显示全部楼层
你说的第一种情况是不会存盘的。

物品这个问题主要是玩家背包有多大, 背包中的物品肯定不会做成enitty,就是个数据结构。
没产生的物品也就是个配置表, 内存读取根据需要创建物品数据结构, 掉落在地面的物品才需要创建成entity用于交互
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-1-11 11:15:42 | 显示全部楼层
柯标 发表于 2019-1-11 10:39
你说的第一种情况是不会存盘的。

物品这个问题主要是玩家背包有多大, 背包中的物品肯定不会做成enitty, ...

感谢解惑,我能理解为对于entity而言,是能自动监控需要存盘的属性的变更情况,一旦有需要存盘的属性发生变更,就加一个标记,等存盘时间到了,就判断该entity是否有需要存盘的属性发生变化,有的话就整体需要存盘的属性序列化发给dbmgr,没有就不操作?


对于第二个问题,如果依赖自动存盘机制,就会把物品做成自定义数据结构,定义如下
<ITEM_INFO>        FIXED_DICT
        <implementedBy>ITEM_INFO.item_info_inst</implementedBy>
        <Properties>
                <id>
                        <Type>        UINT16        </Type>
                </id>
                <type>
                        <Type>        UINT16        </Type>
                </type>
                <num>
                        <Type>        UINT16        </Type>
                </num>
        </Properties>
</ITEM_INFO>

<ITEM_INFO_LIST> ARRAY         <of>  ITEM_INFO </of>   </ITEM_INFO_LIST>

Account中的属性字段
<item_list>
        <Type> ITEM_INFO </Type>
        <Flags>                        BASE                                </Flags>
        <Persistent>                true                                </Persistent>
</item_list>

这种情况下,item_list中的对象上千甚至更多是有可能的(考虑到有些物品需要平铺),如果每次改变其中一个物品的数量,就要把所有对象都存盘一次,就会有很多无意义的消耗
我看每个对象在子表tbl_account_item_list都是一条记录,那么只修改改变的那条记录就可以了吧?
另外,也希望这种记录的databaseID作为一个字段默认出现在检出后的数据中(当然也不是必须:))
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-11 11:22:12 | 显示全部楼层
对, 你可以理解为有改动就整体存, 没有就不存。

物品平铺到不是关键问题, 关键是背包多大,背包大就可能都放了很多物品导致出现这种问题。
当前情况下都是整体存, 你可以自己sql去优化维护, 放到你单独的表中存
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-1-11 11:33:26 | 显示全部楼层
柯标 发表于 2019-1-11 11:22
对, 你可以理解为有改动就整体存, 没有就不存。

物品平铺到不是关键问题, 关键是背包多大,背包大就可 ...

entity是只管是否在内存中,不关心是否是proxy,是否玩家在线,去加载离线玩家数据修改也会自动存盘对吧?有点啰嗦,这个最后一点疑问了

第二个问题,那其实就是看数量问题了,多就不适合这种模式,那我理解为目前主要是用于非存盘对象吧,对于存盘对象,直接用PY_DICT PY_LIST就够用了(唯一问题是游戏外查询不直观)
你上面说会准备优化,会优化成只存盘变更数据吗?如果做到只存盘变更数据,那这个功能就能解决非常多问题了,不然像item的设计,因为不能设计成entity,就只能手动存盘了,会产生与Account数据存盘不同步,甚至数据丢失也不同步的问题
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-1-11 12:09:07 | 显示全部楼层
1: 是的。
2:最好能fixedDict, py字典等序列化更耗, 不过更自由。

优化主要是针对容器优化, 其他数据其实也就一条sql就完成了,  一条sql修改一个字段和多个性能区别不明显。
其他是否优化看下一阶段时间。
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-4-1 15:01:50 | 显示全部楼层
柯标 发表于 2019-1-11 12:09
1: 是的。
2:最好能fixedDict, py字典等序列化更耗, 不过更自由。

现在项目进行到一定程度,这个问题又暴露出来了,目前存一对多的数据,如果不自己用sql维护一张表的话,只有fixedDict和PY_DICT两种选择了,PY_DICT主要有存盘序列化比较耗,数据库查询不直观两个问题,fixedDict主要有存盘数据过大的问题

目前mysql数据库一秒钟也就1000多的事务处理(TPS),如果一个玩家有item表和friend表两个一对多的数据,用fixedDict来存的话,一次自动存盘就会有tbl_Account(1次)tbl_Account_item_dict_values(几十到几百次)tbl_Account_friend_dict_values(几十到几百次),这样每次存一个玩家的数据就会消耗几十到几百的事务处理,玩家量一起来,数据库不就容易出现瓶颈了吗?

为啥对于tbl_Account_item_dict_values这种一对多的表,不能做到变更哪条数据就存哪条数据呢?
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-4-1 15:17:06 | 显示全部楼层
fixedDict、和fixedArray以后会优化, 目前fixedArray不要放过多的数据。

目前你需要存储大量的数组数据, 你可以自己维护sql用api自己增量存储
QQ:3603661
3603661@qq.com
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-4-1 15:26:11 | 显示全部楼层
柯标 发表于 2019-4-1 15:17
fixedDict、和fixedArray以后会优化, 目前fixedArray不要放过多的数据。

目前你需要存储大量的数组数据, ...

有大概时间吗?优化之后还会有那么多sql修改产生吗?

目前还没突破100条,想利用这个特性,不然改成自己用sql维护,上线后就不好改回来了
回复

使用道具 举报

5

主题

5407

帖子

214748万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2147483647

引擎扛把子

发表于 2019-4-1 15:35:01 | 显示全部楼层
你先自己存吧
QQ:3603661
3603661@qq.com
回复

使用道具 举报

171

主题

615

帖子

1935

积分

金牌会员

Rank: 6Rank: 6

积分
1935
发表于 2019-4-1 16:49:14 | 显示全部楼层
发现还是蛮多人问这个问题的,我之前也问过。

楼主说的item 和 friend两种情况,我们没有用数据库的多行来解决这个问题,因为这种一对多,后面会造成这个表行数非常多!!   由于考虑到背包和好友如果都限制数量的话,我们将背包和好友放在mysql的一列去存了。

不过我们不需要对friend 和 item 去数据库做查询,所以这样做就没有太大问题。  唯一存在的问题就是,如果背包或好友只要有一个有变动,那么这一列整个会被update一次,但是也还可以接受,因为控制了数量


不过别的地方我们用到了 ARRAY LIST这种方式,期待对这一块的优化



回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-4-1 17:34:44 | 显示全部楼层
kbengine_one 发表于 2019-4-1 16:49
发现还是蛮多人问这个问题的,我之前也问过。

楼主说的item 和 friend两种情况,我们没有用数据库的多行来 ...

请问一下,你说的一列是什么意思呢?

是在tbl_Account这个表中加多个字段,每个字段表示一种物品,还是加一个字段,存成字符串或者blob来解析呢?

friend是可以限制数量的,但item根本没法限制数量啊,随着游戏的发展,item种类就是越来越多的
回复

使用道具 举报

61

主题

225

帖子

862

积分

高级会员

Rank: 4

积分
862
 楼主| 发表于 2019-4-1 17:56:44 | 显示全部楼层

目前的存盘策略是每个base进程做个定时器,时间一到就把需要存牌的各种数据转成sql语句发给dbmgr进程,然后dbmgr进程慢慢往数据库里写吗?

调用executeRawDatabaseCommand和writeToDB两个方法也是把写好的sql直接发往dbmgr进程吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|KBEngine Forum

GMT+8, 2019-7-18 02:37 , Processed in 0.037361 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表