典型技术问题

1. TcaplusDB表结构发生更变,后台如何做版本控制?

TcaplusDB根据表的版本号(Version No.)解决多版本兼容性问题,即TcaplusDB存储层会存储同一个表不同版本号的数据;因此gameserver或客户端进行数据读写操作时,需要指定表的版本号。

当不同客户端对同一张表进行交替写,并且客户端各自使用不同版本的表定义的时候,pb表和tdr表对于差异字段的处理方式是不同的。

假设gamesvr1: 表有abc字段

假设gamesvr2: 表有ab字段

假设tcaplusDb: 表有abc字段

对于PB表:

1、假设abc是pb表的字段, 两个svr交替写, c字段会清空。

对于TDR表:

1、假设abc是tdr表的一级字段, 两个svr交替写, c字段不会给清空。

2、假设abc是tdr表的二级字段, 两个svr交替写, c字段会清空。

2. TcaplusDB如何处理请求延时?

请求在3s内没有响应时,TcaplusDB会打印包含关键字timeout的错误日志;建议客户端请求代码中也增加超时逻辑或重试次数。

3. TcaplusDB如何保证读写请求稳定性?

TcaplusDB默认采用Master-Slave模式,Master负责用户请求的读写,Slave充当热备节点。当出现QPS突增,读写分流会自动开启,即Master承当写操作,Slave承担读操作直至后台扩容完毕。

4. TcaplusDB是否支持保存策略(retention policy)?

支持,TcaplusDB会默认保留所有数据,支持用户设定保存时间,数据过期会自动淘汰,当前工单支持。

5. TcaplusDB是否支持跨地域迁移?

支持,TcaplusDB同时支持热迁移(采用跨区热备的方式)和冷迁移,支持数据导出为Json文件,也支持MySQL数据导入TcaplusDB,当前均为工单支持。

6. TcaplusDB如何保证热数据?

TcaplusDB采用LRU缓存算法保证数据热度。

7. 对于游戏玩家数据,TcaplusDB如何存储?

一条TcaplusDB记录(Record)即为单个玩家的数据, 按照主键字段或索引进行数据操作。

8. TcaplusDB表创建后可否增加索引或修改主键?

不可以,如有修改需求请重建表。

9. TcaplusDB能否支持事务?

暂不支持,建议将相关的字段定义在同一个表里进行操作,获得类事务体验。

10. 是否会保证一个线程里的非同步请求相关应答会按照顺序处理?是否需要用syncld来进行同步处理?(以功能为主,不使用同步api的情况下)

同一个线程里,同一个key的读写操作是按照顺序处理的,即保序。不同的key的读写操作顺序不保证,如果项目组采用asyncid来标志请求和响应的映射关系,是可以的,这种是透传字段,包括asyncid、sequence、userbuff。

11. delete性能如何?是否需要update命令来替代delete?

delete就是一次普通的写操作,性能上没有问题,项目组可以随时进行delete操作。

12. 线程与并发

TcaplusDB C++ API是单线程实现且不支持多线程,一个tcaplus C++ api对象对应一个request和response,由于TcaplusDB C++ API是非线程安全的,所以不能多个线程使用同一个TcaplusDB C++ API对象。如果需要实现并发场景,推荐单个线程使用单个TcaplusDB C++ API对象。从线上运营来说,TcaplusDB C++ API实例在单个机器上保持1-2个已经足够了,一个TcaplusDB C++ API实例的qps可达到7-10万。 TcaplusDB Go API 单实例支持多协程。

13. SDK内存占用情况如何?

一个TcaplusDB API实例将占用200M左右物理内存,实例采用静态分配的方式,内存消耗主要在协议上,收包发包各自一个结构体,故需要预分配一些内存。注:不同的TcaplusDB API版本,因为支持的单条记录大小不一样,预分配的内存可能有差别。

14. Tcaplus主键可以是结构体?还是只能是基础类型?

不建议使用结构体,理论上结构体是没问题的,不过用结构体后,不便于后期用各种工具或问题定位、回档、提供key。

15. 请求读取数据报错525

一般是后端超时了,如果并发量大,可能是gameserver与tcaproxy之间通信问题,可以看下:

  • tcaproxy是否正常
  • TcaplusDB API版本号是否大于了接入层版本号
  • tcaproxy的TCP连接数目是否超限

16. 分布式索引进行delete有支持where的方法吗?

可以采用分布式索引,读出来,再单条单条的删除。

17. 重新添加的表格组,对应表新增全局索引,回档恢复数据进去,索引都还在吗,还是会重做索引?

分布式索引是在数据插入时进行自动维护的,当我们采用数据导入方式进行时,数据会同步到全局索引去

18. 如果一个表有多个primary_key, 通过指定其中一个primary_key并删除对应的数据吗?

主键,按照delete删除。本地索引,按照deletebypartkey删除。

19. telnet ip port可以通tcapdir地址,但是连接数据库集群失败如何排查?

  • telnet 9999端口
  • 需确认是腾讯云环境还是普通集群环境,腾讯云需要连客户自己的vip+9999端口,普通集群连真实dirip+9999端口
  • 因为一个集群有多个dir,最好拿到api连接日志,看连哪个dir失败,或者连上dir了但proxy版本比api版本高导致失败

20. Tcaplus是否支持单个app下不同的zone能采用不同的协议

Tcaplus支持单个app下不同的zone能采用不同的协议,即zone1为PB协议,zone2为TDR协议

21. 表重建或删除再新建会影响缓存的配置吗?

重建可以保留,删除再新增,缓写就没有了,删表的时候就会删除缓写。

22. 增加列需要重建表格吗?

增加列只用执行在线变更就行。

22. 表结构里的count扩大是否需要重建表?

不需要,可以直接修改,并且不用加版本号,count只能改大不能改小。

23. 删除某一张表或者删除表中的某一行,需要变更tables.xml的版本号吗?

是已经存在的表是不可以删除字段,只能追加字段,如果需要删除字段需要整表删除然后重建。

24.业务侧扩大blob的长度,是否可以支持业务侧无感的动态调整?

可以的,count定义了refer,count值可以修改大,且不需要增加版本号。

25. 表变更修改了一级字段之后是否需要更新缓写呢?

如果这些字段不需要配置缓写,那么就不用动,如果需要配置则要更新下缓写配置。

26. Redis替代场景

26.1 TcaplusDB是否能代替redis的pub/sub功能?

目前TcaplusDB没有pub/sub功能,可以采用list表来模拟实现,类似进程A去list表写数据,进程B从list表读数据这种,会增加代码改造成本。

26.2 是否支持redis的expired(自动到期功能)?

目前TcaplusDB支持数据淘汰,比如账号表设置了30天淘汰,那么会淘汰掉30天内没有任何写操作的数据,是物理删除,即该功能是支持的。

26.3 TcaplusDB Client有setttl,想问下是否还支持api?

单条记录设置setttl,是TcaplusDB API 支持的,但是项目组的使用场景可以设置成全表数据淘汰,即单个表上亿条记录,淘汰标准是1个,比如按照30天内没有任何写操作来淘汰。

26.4 是否可以使用tcaplus的list table来代替redis的stored set功能?

如果是TopN,采用list表即可完成,即该功能是支持的。

26.5 是否有像redis的pipeline之类的,用一次请求(request)就能处理多个query? 比如,有10个query的话,用1个请求就能处理10个query。

TcaplusDB提供了批量操作来满足类似场景的需求,具体可参考SDK:https://github.com/tencentyun/tcaplusdb-go-sdk/blob/v0.0.10/tdr/request/batchget_req.go

27. List表index的增长规则

  1. idx从0开始
  2. idx按照步长1从0开始自增,直到自增到int类型的最大值,然后会选择一个空闲的idx使用,即不管什么情况下,正在使用的idx不会重复
  3. 如果key删除,idx从0开始,也可以保持从上次idx开始 默认从0开始,也可以通过SetFlags设置从上次idx开始

    /*TCAPLUS_FLAG_LIST_RESERVE_INDEX_HAVING_NO_ELEMENTS
     *       设置此标志后,List表删除最后一个元素时需要保留index和version。
     *       ListDelete ListDeleteBatch ListDeleteAll操作在删除list表最后一个元素时,
     *          设置此标志在写入新的List记录时,版本号依次增长,不会被重置为1。
     *
     *       适用场景:
     *                              业务需要确定某个表在删除最后一个元素时是否需要保留index和version
     *                              主要涉及List表的使用体验
     *
     */
     int SetFlags(int32_t flag);
    

    index是不连续的,只会增加比如:1 2 3 4 5 删除了3变成了 1 2 4 5 ,如果AddRecord(2)就变成了 1 2 6 4 5

  4. 如果key下的 list元素都被删除,等同于key也被删除

  5. listaddafter支持队头删除,队尾插入;或者队头插入,队尾删除
  6. listdelete,删除idx
  7. TCAPLUS_API_LIST_PRE_FIRST_INDEX:新元素插入在第一个元素之前 TCAPLUS_API_LIST_LAST_INDEX:新元素插入在最后一个元素之后

28. increase相关接口的上限问题,假如当前值是97,这时候increase5同时上限设置为100会增加成功一部分吗?

不会更新成功,会返回SVR_ERR_FAIL_OUT_OF_USER_DEF_RANGE 错误码

29. tcaplus对表进行insert操作,如果先后2次insert操作的主键相同,第二次是覆盖第一次,还是第二次操作失败?

第二次会报-1293 SVR_ERR_FAIL_RECORD_EXIST insert的记录已存在

30. protoc文件中可以定义的类型,tcaplus都能使用吗?例如any类型

可以,但条件更新没有对any、union支持

31. go sdk 怎么设置遍历备表?

通过SetOnlyReadFromSlave接口调用设置

32. ListGetAllRequest 返回报错 SVR_ERR_FAIL_INVALID_SUBSCRIPT

按照offset和limit拉取时,传的参数不对,请检查offset和limit参数设置

33. 本地索引和分布式索引(全局索引)的创建方式

本地索引在表结构文件中定义,一旦定义无法修改删除;分布式索引在对应的控制台页面(oms或者腾讯云控制台页面)创建,可以修改重建

34. 分布式索引(全局索引)支持字符串的分词模糊搜索吗?

支持like模糊查询,还不支持分词检索

35. 表定义中的字段是否可以删除?

已存在的表不能删除字段

36. PB表的add操作,add因为数据已存在时,有没有办法返回已有数据?

可以,在int SetMessageOption(const ::google::protobuf::Message &msg, int32_t item, const std::string &option) 函数中option设置变更记录的所有字段旧数据,具体参考章节9.TcaplusDB下载中心 pb api中函数注释。

37. TcaplusDB Go SDK支持通过域名的方式连接目录服务器(Tcapdir)吗?

支持通过域名的方式连接目录服务器(Tcapdir)。

38. TcaplusDB的list结构,有接口只查询list内元素数量吗?

目前不能查询一个list的size大小

39. Tcaplus list表元素满时默认的淘汰方式是哪种?

有三种淘汰方式,默认TCAPLUS_LIST_SHIFT_HEAD 移除最前面的元素。

  • TCAPLUS_LIST_SHIFT_NONE: 不允许删除元素,若LIST满,插入失败;
  • TCAPLUS_LIST_SHIFT_HEAD: 移除最前面的元素;
  • TCAPLUS_LIST_SHIFT_TAIL: 移除最后面的元素

sortlist表不支持业务指定淘汰方式,对于SortList,当用户进行ListAddAfter时,List数目超过最大元素个数N时,对于正序(从小排到大)总是保留最小的N个元素,也就是说插入的元素比当前最大值还大时,会插入失败(因为立即被淘汰),而倒序则反之,总是保留最大的N个元素。

40. Tcaplus 单行记录的淘汰假如设置了300秒淘汰,是插入后300秒淘汰吗,这段时间怎么续租约呢?

表级别数据淘汰,是根据记录最后修改时间淘汰;即update或replace会自动续期。精确度大概为天级别。 适合场景:如保留最近30天的邮件或战斗记录。 记录级别通过setttl设置和续期, 适合对ttl时间比较精确或不同记录的淘汰时间不同的场景。 精确到毫秒。

41.一个TcaplusServer对象只能访问一个set内的不同zone

1、多个TcaplusServer对象是不是可以实现跨set访问--只能访问一个set,不能跨set;跨set可以用多个api,即多个TcaplusServer对象 2、多个TcaplusServer对象内存占用如何--每个api实际内存占用在40M左右

42.UpdateNetwork api的这个接口,内部会调用类似sleep或epoll_wait的接口吗?

UpdateNetwork是用户线程,不会sleep,通过网络线程收发包,只有网络线程会epollwait,网络线程用户不用关注

43.同时调用了 SetResultFlag(2) SetResultFlagForFail(0) 会怎样表现呢?

建议不要一起用,SetResultFlagForFail和SetResultFlagForSuccess推荐这两个函数搭配使用。如果同时用调用了 SetResultFlag(2) SetResultFlagForFail(0),会以最后一次设置为准

44.Tcaplus可以直接使用RepeatedPtrField作为表字段做存储操作吗?proto基础类型和结构类型作为基础tcaplus表字段存储方式有什么区别吗?

可以,无区别,注意结构嵌套深可能更消耗cpu。

45.咨询下Tcalpus有原子操作的api吗,是否支持事务?

所有操作单条记录的请求都是原子性的; Tcaplus有乐观锁,支持单key的事务,TCAPLUS_CMD_INCREASE_REQ自增自减操作、单key下的条件更新操作支持,其他操作不支持事务

46.FieldGet接口里面的dottedpaths 字段,如果为空,是返回所有字段呢?还是仅返回key字段,其他普通字段全部为空呢?

FieldGet是返回需要的字段,如果为空的话只有key字段,想要返回全量字段可以使用Get

47.getbypartkey情形下,业务只想获得符合条件的记录条数,可以只返回记录条数吗?

可以通过调用SetResultLimit(1) 来获取一条记录,但本次可以通过GetRecordMatchCount 来拉取总数。

48.list类型表的ListNum支持修改吗?

list类型表的ListNum支持改大,不能改小;ListNum为必填属性,一般由业务预估大小在表定义中设置;

49. 表结构里的size扩大是否需要修改字段的version?

不需要,可以直接修改,size只能改大不能改小。

50. 在不知道list表的index的情况下,有没有方式能获取到最新的n条记录?

如果本身插入就是按时间顺序addafter 的话,可以直接从尾部listgetall,SetResultLimit可以指定数量参数。或者使用sortlist表,加个时间字段,按时间排序。

51.tdr go api的 xml转go文件的工具在哪里下载转换?

https://git.woa.com/tsf4g/TdrCodeGen python tdr.py table.xml,得到相应表的go源码目录table/table.go,将table放到自己的go的工程目录即可使用

52.API访问报错:dir sign up fail, ret:-279,如何处理?

检查业务密码是否正确;检查dir地址是否正确

53.Tcaplus能否支持模糊查询,以及忽略大小写?

支持模糊查询,需要创建分布式索引查询。区分大小写

54.同一个进程里可以有多个不同的TcaplusService::TcaplusServer吗?

可以的,持有多个service api的handle,分别初始化

55.内部用户新机器部署sdk出现无法连上dir的问题,Can't find a valid dir server(注:仅限内部用户可能会遇到,腾讯云等外部用户不会产生该问题)

DNS设置问题,通过在http://scr.ied.com/#/sojob/create上重新刷dns解决

56.全局索引模糊查询咨询:

  1. 一张表的多个字段都建了全局索引,查询(A and B and C)的时候。会求ABC的交集再回表拉数据。还是找到满足某一个条件A的主键就回表拉数据,后面再过滤条件B,C?
  2. ABC的交集再回表拉数
  3. 对于like %str% 这种字符串查询是走全表扫描吗?还是也可以支持,比如字符串AA_BB_CC,可以索引命中AA或BB或CC?
  4. %str%这种基本上会走全表扫描查询了,所以不建议使用前缀模糊匹配查询;
  5. 对一张表的全局索引的查询,如果数据量多、查询很多导致负载高的时候是支持扩容的吗?
  6. 可以支持扩容的,但是扩容是需要一定的时间的,所以建议提前预估好

57.GO api中的Error()返回的是string如何获取错误码code?

GO api中的Error()的string类型返回值可以通过terror.ErrorCode强转错误码,获取error code

  if err != nil {
                terr,_ := err.(terror.ErrorCode)
                fmt.Println(terr.Error())
        }

58.请问list表,TCAPLUS_API_LIST_GETALL_REQ查询list表所有数据,返回的数据是有序的吗?

需要考虑业务侧设置的插入顺序和元素满时淘汰策略

  • TCAPLUS_LIST_LAST_INDEX : 队尾插入,listgetall的时候,是按照插入顺序返回的
  • TCAPLUS_LIST_PRE_FIRST_INDEX:队首插入,listgetall的时候,是按照插入顺序逆序返回的
  • 当list成员满的时候,需要进行淘汰,淘汰也分为队首淘汰,或者队尾淘汰,根据业务侧的设置来淘汰

59.ttl相关的操作,是不是不支持在 insert数据的时候,同时设置ttl?

是的,需要先插入后再设置ttl

60.过期淘汰的数据是否会同步删除全局索引系统中的数据?

过期淘汰的数据会同步删除掉全局索引系统里的数据

results matching ""

    No results matching ""