使用问题

最近更新时间:2019-08-08 14:28:28

TcaplusDB 存储层读写分离怎么设置?

TcaplusDB 存储层支持读写分离,如果您有需要,请 提交工单 申请。

TcaplusDB 支持数据淘汰吗?

TcaplusDB 支持表级别数据淘汰,淘汰的依据是记录最后的写时间;TcaplusDB 支持基于 key 的数据淘汰,如果您有需要,请 提交工单 申请。

如何获取某个响应包错误码的含义

推荐您在代码里采用在 gameserver 里调用函数TcapErrCode::TcapErrCodeInitTcapErrCode::GetErrStr函数来获取错误码,也可以本地搜索 TcaplusDB API 的头文件。

TcaplusDB 的数据结构有哪些?

TcaplusDB 支持的数据结构有 list 数组、按照部分 key 查询(索引)、key-value、key-object(即单个 key 的 value 值可以是任意的数据结构,例如 gameserver 可以将 lua table 序列化到 value 字段里)。

TcaplusDB 的乐观锁原理和使用方法?

举个抢火车票例子:

  1. 100个人去抢同一张火车票,此时火车票的记录版本号是10,100个人 get 时,都是记录版本号为10。然后这100个人拿着记录版本号为10来抢火车票。
  2. 100个人来对这张火车票进行写操作,因为写操作后记录版本号++,对于单个 key 的操作,tcapsvr 工作线程是排队的,第一个人抢到了火车票,此时火车票的记录版本号为11了,而剩余的99个人来抢时,拿着的记录版本号还是10。
  3. tcapsvr 在处理这99个人的写请求时,全部报错了,因为 tcapsvr 端的记录的版本号和请求里的版本号不一致导致的,并发时的原则:
    • N个请求,只是需要第一个请求成功,剩余的N - 1个请求失败,则采用版本保护规则。
    • N个请求,需要N个请求全部执行完毕,则不需要版本保护规则,TcaplusDB 这边对同一个 key 的操作。

排队执行调用函数SetCheckDataVersionPolicy,其值包括:

  • CHECKDATAVERSION_AUTOINCREASE:检测记录版本号,只有当该版本号与服务器端的版本号相同时,该版本号才会自增 。
  • NOCHECKDATAVERSION_OVERWRITE:不检测记录版本号,强制把客户端的记录版本号写入到服务器中。
  • NOCHECKDATAVERSION_AUTOINCREASE:不检测记录版本号,将服务器端的版本号自增。
  • 默认类型为CHECKDATAVERSION_AUTOINCREASE,推荐您使用。

list 表的使用场景及注意事项?

凡是存在1:N的使用场景,N < 1024时,优先考虑 list 表,例如存储玩家最近的100封邮件、最近的100场战斗记录等,list 表支持按照队头插入、队尾淘汰,队尾插入、队头淘汰,支持按照插入时间排序的 Top N 操作,单个 key 下的单元个数可以通过表变更修改大,因为需要兼容旧数据不能修改小。采用 listgetall 可以获取单个 key 下总的记录数目,推荐按照 offset 自己维护,limit 等于一定阈值的方式获取数据,listreplace、listdelete、listdeletebatch 时需要指定正确的 index。listaddafter 时需要指定单个 key 下的元素单元个数满时淘汰的规则,调用 SetListShiftFlag 函数设置所以 list 表有2个增加方向,2个获取方向,就是4种可能:

  1. A、B、C、D、E,按照 offset = 正数,limit = 2 拉取就是A、B,C、D,E。
  2. A、B、C、D、E,按照 offset = 负数,limit = 2 拉取就是D、E,B、C,A。
  3. E、D、C、B、A,按照 offset = 正数,limit = 2 拉取就是E、D,C、B,A。
  4. E、D、C、B、A,按照 offset = 负数,limit = 2 拉取就是B、A,D、C,E。

另外,调用GetRecordMatchCount可以获取记录的总数。

insert、update、replace 有什么区别?

insert 操作,当 key 不存在时会进行插入,当 key 存在时,会返回错误码:TcapErrCode::SVR_ERR_FAIL_RECORD_EXIST
replace 操作,当 key 不存在会进行插入,当 key 存在时,如果采用了乐观锁,则根据乐观锁的结果执行不同的操作,成功则进行替换,失败则返回错误码:TcapErrCode::SVR_ERR_FAIL_INVALID_VERSION;如果没有采用乐观锁,直接替换。
update 操作,当 key 存在,如果采用了乐观锁,则根据乐观锁的结果执行不同的操作,成功则进行更新,失败则返回错误码:TcapErrCode::SVR_ERR_FAIL_INVALID_VERSION,如果没有采用乐观锁,直接更新;如果key不存在时,则返回错误码:TcapErrCode::TXHDB_ERR_RECORD_NOT_EXIST

如何获取某个表的记录数目?

TcaplusDB API 接口里有 count 命令字,如果采用 tcaplus_client 可以采用 count 表名命令获取表的记录数目。

TcaplusDB 支持遍历操作吗?

TcaplusDB 支持遍历操作,包括 generic 表、list 表的遍历操作,遍历时注意设置从 tcapsvr slave 上遍历数据(从 tcapsvr slave 上遍历数据,不会影响 tcapsvr master 对外提供服务),即接口:SetOnlyReadFromSlave(bool flag)

TcaplusDB 支持部分字段更新吗?能只是获取部分字段吗?

TcaplusDB 支持部分字段更新,推荐更新记录、获取记录时,显式的调用接口SetFieldNames(IN const char* field_name[], IN const unsigned field_count)确定本次读写操作的字段,减少无效字段的带来的网络流量开销。

TcaplusDB 对单个 key 连续操作是保序的吗?

对于同一个 gameserver,同一个 key 的操作保序,不同 key 的操作不保序。对于不同的 gameserver ,都不保序。

TcaplusDB 支持表定义变更吗?

TcaplusDB 支持表定义变更,如果简单的增加 value 字段、修改宏请采用表变更操作;其余的场景,需要动态修改表结构,即采用数据迁移 + Ulog 流水方式实现表定义变更,请 提交工单 申请。

gameserver 如何剔除某个无效的 tcaproxy(接入层)节点?

TcaplusDB API 在这里对 tcaproxy 异常做了容灾的处理,API 剔除无效的 tcaproxy 进程的方式主要有2个:

  1. API 物理上认为某个 tcaproxy 不可用,API 每隔1秒对起链接的所有的 tcaproxy 发送心跳检测包,如果某个 gameserver 在10s内没有从 tcaproxy 收到相应的心跳回包,则 API 会主动断开与 tcaproxy 的 TCP 链接, 在下个 onupdate 时主动去链接该 tcaproxy 。
  2. API 逻辑上认为 tcaproxy 不可用,是每隔10s去计算下某个 tcaproxy 的请求和响应比,作为判断依据,其中 API 为某个请求包超时的阈值是3s,大于3次则认为该 tcaproxy 不可用,请求不会再发给该 tcaproxy ,在60s后发送 getmetdata 请求,如果 tcaproxy 能够正确处理 getmetadata 的请求,则 API 再次认为该 tcaproxy 可用,请求会再次发送给该 tcaproxy。

从现象上看,gameserver 在10s内发现某个 tcaproxy 不可用,则不会再向该 tcaproxy 节点发送数据了。

gameserver 是怎么选择 tcaproxy(接入层)节点的?

gameserver 本地维护了一致性的 Hash 环,凡是某个 tcaproxy(接入层)节点认证通过后即增加到 Hash 环上,如果某个 tcaproxy(接入层)节点缩容后或者由于机器异常导致 gameserver 与 tcaproxy(接入层)之间的 TCP 链接断掉后,gameserver 会从 Hash 环上摘除该 tcaproxy(接入层)节点。gameserver 根据请求里的主键计算 hash 值(如果是 batchget 请求,会随机的选择单个 tcaproxy(接入层)节点),然后在一致性 Hash 环上选择单个 tcaproxy(接入层)节点发送出去。

怎么判断响应包分包是否已经结束?

遍历,请按照 state 判断遍历是否结束,即接口 GetState,其余分包场景,请根据函数HaveMoreResPkgs判断分包是否结束。

GetRecordCount 与 GetRecordMatchCount 的区别?

一次请求可能有N次响应回包,如果有多次回包,则 GetRecordCount 是指本次响应包里的记录条数,GetRecordMatchCount 指存在 tcapsvr(存储层)端的数据记录(单个 key 总的记录条数)。

TcaplusDB 有透传的字段吗?

TcaplusDB 的 CS 协议分为 Head、Body 两部分,Head 里 UserBuff(最大1KB)、AsyncID、Sequence 都是透传的字段,请您根据实际需要使用。

SetResultFlag 的作用?

写操作时,响应包里支持返回记录,读操作调用该函数无效,具体的 result_flag 值含义如下:
0表示:只需返回操作执行成功与否,不需要返回 value 字段。
1表示:返回与请求字段一致的数据。
2表示:须返回变更记录的所有字段最新数据。
3表示:须返回变更记录的所有字段旧数据。

SetResultFlagForSuccess 接口可以设置成功场景下,返回的数据情况;SetResultFlagForFail 接口可以设置在失败场景下,返回的数据情况。

increase 操作可以一次对多个 value 字段进行 increase 操作吗?如果 key 不存在的场景呢?

increase 操作可以一次对多个 value 字段进行 increase 操作,需要 gameserver 传递的请求里对多个字段都进行了赋值,如果某个 key 不存在时,再进行 increase 操作,此时可以通过函数 SetAddableIncreaseFlag 设置;如果 key 不存在时,插入该 key 并进行 increase 操作,该 key 的非 increase 字段不会实际存储,在读取该条记录时非 increase 字段会采用默认值;如果 key 存在,则直接会执行 increase 操作。

TcaplusDB 有压缩功能吗?

TcaplusDB 有压缩功能,采用的压缩算法是 Google snappy 压缩算法,包括协议压缩,即 gameserver <--> tcaproxy(接入层)间的请求包/响应包的压缩功能;数据压缩,即 tcapsvr(存储层)在数据存储时会压缩需要存储的数据,如果您需要节省 gameserver <--> tcaproxy 间的网络流量,推荐开启协议压缩,调用 TcaplusDB API 的函数 SetCompressSwitch,推荐您开启 tcapsvr(存储层)压缩,节省磁盘空间、提高 IO 磁盘性能的同时压缩、解压缩耗费的 CPU 也是可控的问题。

TcaplusDB 在读取记录时,有哪些省流量的方法?

TcaplusDB 读取记录时,支持在固定时间内记录没有变化则不返回 value 字段、记录版本号没有变化则不返回 value 字段,具体的见函数 SetFlags 函数。

TcaplusDB API是线程安全的吗?

TcaplusDB API 是非线程安全的,主要是 tlog、tdr 等组件是非线程安全的,推荐单个线程采用单个 API 对象,单个游戏区采用单个 API 对象,如果需要跨游戏区交互,建议单个 gameserver 维护多个 API 对象。

tcaproxy(接入层)的容灾是怎么做的?

tcaproxy(接入层)采用对等设计方案,即单个游戏区下面的所有 tcaproxy(接入层)节点都包含了单个游戏区下所有表的路由信息,如果某个 tcaproxy(接入层)故障后,只要其余的 tcaproxy(接入层)节点不会过载,则 gameserver 会剔除异常的 tcaproxy(接入层)节点,不会影响 gameserver 的使用,tcaproxy(接入层)没有单点的风险。

tcapsvr(存储层)的容灾是怎么做的?

tcapsvr(存储层)采用一主(tcapsvr master)一从(tcapsvr slave)的模式运行,tcapsvr master/slave 实时的在同步数据,采用同城异 IDC 部署,确保主从同步时延小于10ms,如果 tcapsvr slave 异常,不会影响 gameserver 的使用(没有开启读分流, gameserver 的请求是 tcapsvr master 处理,如果开启读分流后,tcapsvr slave 会协助处理部分读请求),DBA 进行 tcapsvr slave 重建即可;如果 tcapsvr master 异常,则 tcapsvr slave 会进行故障恢复,DBA 再申请新的机器的 tcapsvr slave 重建即可,tcapsvr(存储层)没有单点的风险。

TcaplusDB 支持回档吗? 支持的回档粒度如何?

TcaplusDB 支持回档,包括全区全服、单张表、千亿条记录回档N条记录,支持冷备时间回档(最近的凌晨01:05:00)、精确时间回档(秒级别)、模糊回档(您指定回档的规则),精确时间回档的速度请参照300GB数据、200GBUlog流水,耗时2小时左右,回档的原理,冷备时间回档即替换引擎文件,精确时间回档,将冷备的引擎文件 + 执行Ulog流水,执行到需要回档的时间点即可,基于 key 的回档需要您配合,先对这些 key 封号,TcaplusDB 回档完毕后,再对这些 key 解封。

TcaplusDB 的安全怎么做的?

如果 TcaplusDB 部署在 IDC 环境,会直接部署在内网,进行物理安全隔离;如果 TcaplusDB 部署在非 IDC 环境,API 通过 AppKey 进行身份校验,防止非法数据访问;Protobuf API 提供对 String 和 Bytes 类型字段加解密存储的功能。

TcaplusDB 有过载保护吗?

接入层、存储层都有进程级的过载保护措施,保障业务高峰时服务不雪崩。

TcaplusDB API的单实例内存和 CPU 消耗?

API 单实例内存消耗最大73MB、CPU消耗最大30%。

TcaplusDB 单个游戏区表的个数是多少?

TcaplusDB 单个游戏区表的个数最大是256,如果您单个游戏区下的表的数量大于256,可以采用再新增新的游戏区或者将表进行合并操作,如果需要技术支持,请 提交工单 申请。

TcaplusDB 对 key 和 value 字段的限制是什么?

generic 表 key 字段的个数是4,list 表 key 字段的个数是3,单个 key 字段的长度是1024B,generic 表的 value 字段的个数是128,list 表的 value 字段个数是127,单个 value 字段大小是256KB,整体记录最大是1MB。

TcaplusDB 按照部分 key 查询(索引)的效率怎么样?

推荐在业务场景1:N(N > 1024)下使用部分 key(索引)查询,单个索引键下的主键个数 = 10GB/单条记录主键的大小,单次读写索引操作耗时100ms左右(单条索引键下有10w+以上的数据记录)。

TcaplusDB 的冷热数据交换原理是什么?

TcaplusDB 采用内存 + SSD 盘存储,单个引擎文件,前1GB映射在内存,热数据尽量放在内存,冷数据放在磁盘,采用 LRU 算法进行冷热数据交换,gameserver 的 get 操作触发 LRU 换入操作,tcapsvr(存储层)的 LRU 线程负责 LRU 换出操作,尽量保证热数据存储在内存里,确保 cache 命中率高、单次读写延时低。

TcaplusDB 备份文件存放的时间?

TcaplusDB 备份的引擎文件保存25天,Ulog 流水保存15天,海外环境,各个 TcaplusDB 环境是不一样的,您可根据具体的 TcaplusDB 环境向 客服咨询

gameserver 与 tcaproxy(接入层)是全链接吗?

为了节省gameserver、tcaproxy(接入层)维护 TCP 链接的成本,gameserver 支持选择部分 tcaproxy(接入层)建立链接。

TcaplusDB 的数据怎么做数据分析?

TcaplusDB 的数据可以导出任何格式,包括 json、pb 等方式,可以入库 tdw 等数据分析系统;TcaplusDB 支持将实时的数据导入到 MySQL 数据库等。

TcaplusDB API 的超时机制是什么?it is timeout 错误什么意思?

TcaplusDB API 对每个请求分配个 ID,发送成功后,将 ID 压入判断超时数据结构里,如果该请求的响应包回来后,则从数据结构里删除该 ID,如果在3秒内该请求的响应包还没有被应用层处理,则会显示打印错误日志,关键字包括 it is timeout,此时需要看下 gameserver 是否被阻塞,可能是 tcaproxy(接入层)在向 gameserver 端回包时丢包,可能是响应包已经到达了 gameserver 端,但是 gameserver 端没有及时处理
TcaplusDB 推荐您自己实现超时机制,这样可以对超时的请求进行重试等处理。

TcaplusDB API 的 SendRequest、OnUpdate、ReceiveResponse 函数具体的作用是什么?

SendRequest 发送请求,本次的发送请求可能已经发送到网络上,也可能被压在 gameserver 与某个 tcaproxy(接入层)的发送通道里;ReceiveResponse 是从本地接收队列里获取响应包;OnUpdate 是负责将发送队列的请求发送到网络和从网络接收响应包到接收队列。在消息驱动编程模式下,OnUpdate 调用推荐的调用频率是1ms一次。

TcaplusDB 写操作流水如何解析?

TcaplusDB 对所有的写操作记录了 Ulog 流水,如需解析 Ulog 流水,请 提交工单 申请。

TcaplusDB 如何实现字段全局自增的功能?

您需要定义单张表,设置单个 key,单个 value 字段类型设置为 int64_t(多个 value 字段可以实现计数器数组),多个 gameserver 可以并发对单个 key 进行 increase 操作(不需要设置版本保护规则),并且得到本次返回的 increase 结果,则该次 increase 的结果是全局自增的。

关于部分 key 查询(索引)定义有哪些规则?

索引键必须是主键的一部分,索引键必须包含分表因子,索引键不能是主键。

单个表 id 和 name 互查怎么实现?

采用第三个 key 字段 x 作为分表因子,在 id 和 x、name 和 x 上建立索引实现该功能,例如存储玩家信息时,可以加上玩家的省份地址,即主键是 uin、name、省份地址,索引键是 uin、省份地址,name、省份地址。

表清理会删除数据吗?

表清理会删除数据,如果该表配置的有缓写,可以选择是否同时删除缓写里的数据。

tcaproxy(接入层)是怎么选择 tcapsvr(存储层)的?

每个表定义的有分表因子,如果没有定义分表,分表因子则默认是主键,tcaproxy(接入层)根据 hash(分表因子)%1w,选择对应的 tcapsvr(存储层),故分表因子离散度要高。

TcaplusDB 单张表的最大大小是多少? 记录条数限制是多少?

单个表能细分到1w个数据分片,每个数据分片是256GB,即单个表的总大小是1w * 256GB,单个表没有记录条数的限制,单个表的记录条数和单条记录大小是相关的。

tcaplus_client 支持二级字段及以上字段显示吗?

是支持的,请执行 help select,查看 select * into a.xml 的使用方法。

TcaplusDB 锁的级别是什么?

TcaplusDB 锁的粒度是记录级别。

TcaplusDB 支持多表事务操作吗、支持批量写操作吗?

TcaplusDB 目前不支持多事务操作,即同时提交多个操作,如果后面操作失败则回滚所有已做操作。对于这样的情况,通常需要从业务侧解决。可以采用“先扣再加”的策略,或记录重要操作的对账日志等,也暂时不支持批量写操作。

TcaplusDB 表变更时,需要注意什么?

  1. 只能增加新字段,不能修改原有字段类型、名称,更不能删除原有字段,如果需要修改这些,请采用动态修改表结构技术方案。
  2. value 字段中的数组或字符串类型可以加长度,但不能减短。如果需要修改这些,请采用动态修改表结构技术方案。
  3. 新增字段对应的 version 要在原有版本号上加1,相应地整个 xml 文件的版本号(文件最上面定义的)也要加1(与新加出来的字段版本号一致)。需要先对 TcaplusDB 的表做变更,再对 gameserver 端的表做变更。您如果需要动态修改表结构,TcaplusDB 是支持的,请 提交工单 申请。

TcaplusDB 表定义时需要注意什么?

TcaplusDB 表定义时,需要注意:

  1. count 字段的需要增加 refer 字段。
  2. 分表因子需要高度离散。
  3. 索引键不能和主键一样。

TcaplusDB 在业务上线前需要做哪些演习?

业务上线前,需要做压测、tcapsvr(存储层)故障恢复、tcaproxy(接入层)扩缩容、tcapsvr(存储层)扩缩容、回档、过载保护等演习。

TcaplusDB 例行的运维操作时间段是?

TcaplusDB 每日01:00 - 07:00会进行数据搬迁、数据淘汰、数据备份等运维操作,推荐您在这些时间段内的机器物理指标告警暂时可以忽略。

TcaplusDB API 升级是前向兼容的吗?

TcaplusDB API 升级是前向兼容的,已经有的接口、命令字、功能不会修改。

tcaproxy(接入层)扩缩容的速度如何?

tcaproxy(接入层)扩缩容不需要数据搬迁,故扩缩容耗时仅仅是起、停 tcaproxy(接入层),秒级别的。