分布式数据库和Hadoop都不够好,于是我们设计分布式SQL计算系统(2)
举例说下如下的几种策略: 列表:以登录省份作为均衡字段为例 取模 hash:按 4 取模,以用户 id 作为均衡字段 范围: 从 0 到一亿,以用户 id 作为均衡字段 取模 hash 和范围结合:先范围,再取模,以用户 id 作为均衡字段 查询举例说明查询操作,基本信息如下: 用户表 tab_user_info 如下: 用户登录表 tab_login_info 的结构如下: 排序排序的关键点是节点之间存在大小关系,大的 key 或者 key 范围放到节点 id 大的节点上,然后在节点上排序,获取数据的时候根据节点 id 大小依次获取. 以如下 sql 为例,某一注册时间范围内的用户信息,按照年龄和 id 排序: select * from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? order by u_id 执行计划可能为: Map: select * from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? order by u_id Shuffle: 执行完成之后,这种情况下由于需要按照 u_id 进行数据洗牌,所以各个存储节点上需要按照 u_id 进行划分.例如有 N 个计算节点,那么按照(最大 u_id- 最小 u_id)/N 平均划分,将不同存储节点上的同一范围的 u_id,划分到同一个计算节点上即可(这里的计算节点存在大小关系). Reduce: select * from tab_user_info t order by u_id 分组聚合关键点和排序类似,节点之间存在大小关系,然后在节点上分组聚合,某一注册时间范围内的用户,按照年龄分组,计算每个分组内的用户数: select age,count(u_id) v from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? group by age 执行计划可能为: Map: select age,count(u_id) v from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? group by age Shuffle: 执行完成之后,这种情况下由于需要按照 age 进行数据洗牌,考虑到 age 的唯一值比较少,所以数据洗牌可以将所有的记录拷贝到同一个计算节点上. Reduce: select age,sum(v) from t where group by age 连接 ?首先明确 join 的字段类型为数字类型和字符串类型,其他类型如日期可以转换为这两种.数字类型的排序很简单,字符串类型的数据排序需要确定规则,类似 mysql 中的 collation,比较常用的是按照 unicode 编码顺序,按照实际存储节点的大小等;其次 join 的方式有等值 join 和非等值 join;以如下常用且比较简单的情况为例. 以如下 sql 为例,某一注册时间范围内的用户的所有登录信息: select t1.u_id,t1.u_name,t2.login_product from tab_user_info t1 join tab_login_info t2 on (t1.u_id=t2.u_id and t1.u_reg_dt>=? and t1.u_reg_dt<=?) 执行计划可能为: Map: 由于是 join,所有的表都要进行查询操作,并且为每张表打上自己的标签,具体实施的时候可以加个表名字字段,在所有存储节点上执行 select u_id,u_name from tab_user_info t where u_reg_dt>=? and t1.u_reg_dt<=? select u_id,login_product from tab_login_info t Shuffle:这种情况下由于需要按照 u_id 进行数据洗牌,考虑到 u_id 的唯一值比较多,所以各个存储节点上需要按照 u_id 进行划分,例如有 N 个计算节点,划分到同一个计算节点上. Reduce: select t1.u_id,t2.login_product from tab_user_info t1 join tab_login_info t2 on (t1.u_id=t2.u_id) 子查询由于子查询可以分解成具有依赖关系的不包含子查询的 SQL,所以生成的执行计划,就是多个 SQL?的执行计划按照一定的依赖关系进行依次执行. 与已有系统的区别和优点
应用场景 ?最后列举一些应用场景
(编辑:ASP站长网) |