如何在 kv 系统中支持简单的 SQL

现在部门内进行数据收敛,特征相关的指标会逐渐收敛到 XFS 系统中。目前已经建设有 OFS(order feature system)、PFS(passenger feature system)。年后会建设 DFS(driver feature system)。

这些系统有共同的特征,根据 XID + 几个额外的参数来进行特征查询。而特征的具体存储可能是在 Rockstable(未来也可能是在 fusion),或者是在 MySQL,还可以来源于其它跨部门第三方系统的 API。

之前 XFS 对外主要提供 thrift/http 接口,大概会有 SET/GET/MSET/MGET 这么几种接口。但因为有一些特征查询时要求传参数,所以在最初的设计中没有选用 redis 协议(嗯,这个理由是我猜的)。

不过,经过了组内同学很长一段时间的特征查询开发,会发现在特征方面,所有的查询需求都是可以使用 SQL 来表达的。

比如我们 GET 类的需求:

thrift:GET
params:
  order_id => 3423231212323232323
  feature_key => order_fee
  other_param => xxxyyyzzz

=>

select * from ofs where order_id = 3423231212323232323 and feature_key = 'order_fee' and other_param = 'xxxyyyzzz'

如果是 set 类的需求:

thrift:SET
params:
  driver_id : 123213213123123
  feature_key : driver_force_offline
  feature_val : 1

=>

update dfs set feature_val = 1 where driver_id = 123213213123123 and feature_key = driver_force_offline

后来还有一个新的模块,对外提供把不同的服务的数据聚合起来的功能,但只从需求上来讲,也可以用 SQL 来表达:

select ofs.feature_val, dfs.feature_val where driver_id = 123123123123 and order_id = 231321321321

不过这种 SQL 式的表达也有缺陷,如果下游服务不在自己的掌控范围内,有可能会出现字段名字相同但业务含义不同的情况下,这种情况下,我们可以把 SQL 拆分为多条,但放在一个请求中发送给服务端。

sql_arr: ["select xxx", "select yyy"]

因为考虑到 XFS 系统的特殊性,我们会限定 where 条件中只有 driver_id 和 feature_key 可以使用 in 操作符,来传递多个条件来进行查询。其它 where 条件都使用 and 并列。

然后 SQL 要怎么做解析呢?笔者曾经实现过从 SQL 转换到 elasticsearch 的 DSL 的轮子,实际上 where 就是一个简单的 bool 表达式,解析之后是简单的 AST。对 where 的 AST 进行遍历,就可以拿到 bool 表达式的条件列表。对这部分知识感兴趣的同学可以移步这里

如果真的为 xfs 来实现一套 SQL 到 RPC 的映射关系,技术上没是可行的。但问题可能在于如何把 SQL 和谐地整合进在线接口。如果真的要对下游用户友好,还要去支持 MySQL 的协议。如果不支持的话,那就只能实现像下面这样的 thrift/http 接口:

thrift:GET
param: sql=> "select"

或者
thrift:GET
params: sql_arr => ["select aaa", "select bbb"]

实际上可能还不如文章开头提到的简单的 thrift 接口好使。。。

遇到目前这种多系统对接的问题时,也有同学推荐使用 GraphQL。GraphQL 也算是一种 DSL,但在企业里推广新的 DSL 时,都会遇到“新语言”问题。不单要考虑自己的系统能支持这种 DSL,还要考虑对接方的各种语言中是否能有成熟的 SDK 来帮助其快速接入(难道你造一套 DSL 还自己帮 php/c++/go/java/node 们全实现一套 sdk?)。如果对接方使用语言的 sdk 语言有 bug,那怎么解决。这些都是比较麻烦的问题。而 SQL 这样存在了几十年的 DSL,你只需要在自己的系统里进行解析并对应到各种 RPC 请求(包括直接访问存储)就好。

结论:支持什么 SQL/GraphQL 啊,thrift 大法好

如何在 kv 系统中支持简单的 SQL
Share this