Sparrow

分布式数据库中间件

简介

在类似订单的业务环境中,订单的记录会随着时间不断的增长。而走完整个周期的订单,时间越久,被访问到的机率就越小。

但越新的订单,访问频率越高。基于这么一个前提,做出一个简单的预测,如果经过一段时间后,订单量积累到一个非常可观的值,

影响到热数据的CURD效率,那么就必须制定一个可行的解决方案。该中间件就是为此而生。其通过对业务数据进行轻、重、热、冷横竖切分,

让每个块都保持一个轻量级状态。从而达到保证效率的目的。

安装依赖库

# 环境基于python2.7

pip install -r requirements.txt -i http://pypi.douban.com/simple --trusted-host pypi.douban.com --allow-external mysql-connector-python

配置文件

# 配置环境 [debug|sandbox|production(默认)] (可以写入具体执行用户的.bashrc文件中)

export JI_ENVIRONMENT=debug

# 转存周期 亦即多久从热库转存一次数据到冷库 d以日为周期, w以周为周期, m以月为周期

DUMP_CYCLE

# 数据转存所需时间 单位秒

DATA_FLY_TIME

# 数据库默认名称 详细配置中可做差异配置

DATABASE

# 数据库默认端口 后面详细配置中可做差异配置

DB_PORT

# 每次最多返回的记录数

DB_RESULT_LIMIT

# 热\冷库的时间线字段

TIME_LINE_FIELD

# 时间线字段的倍率 为了支持时间单位毫秒\纳秒所设, 仅用在dump脚本中, 1为妙, 1000为毫秒...

TIME_X

# 日志路径 注意读写权限

LOG_FILE_BASE

# 记录ID刻度的Key

IDsKeeper

# Redis相关配置

REDIS

DB_S

# 具体的域配置 [states.DBDomain.light.value|states.DBDomain.hot.value|states.DBDomain.cold.value], 对应轻\热\冷

domain

# 读写模式 [states.RWMode.SW_SR.value|states.RWMode.BW_AR.value], 对应单例写\单例读, 均衡写\聚合读, 一般轻库\冷库单写单读, 热库均衡写\聚合读

rw_mode

# 是否禁用该域 [True|False] 被禁用的域,配置信息不被解析

disable

# 连接池大小 注意: 所有的连接池加起来不能超过数据库环境变量max_connections, (参考命令: SHOW VARIABLES LIKE 'max_connections';)

# 包含转存脚本的连接数

pool_size

冷库格式

冷库需提前创建好,按月份,每月一个库,格式如sparrow__2016__1, 数据库名称\年\月之间用双下划线间隔.

每个冷库里面的数据表,及表的结构,索引都要与热库一致.不然转存数据会失败.

转存的时间

如果转存周期为'w',那么在进入当前周期时,就可以执行转存脚本.

crontab格式如 '* * * * 1 cd ~/sparrowt/task_scheduler && /usr/bin/python dump.py', 注意用户权限.

在周期末时,可以执行clear_expire_in_hot.py来清理热库中已被转存的数据.

crontab格式如 '* * * * 7 cd ~/sparrowt/task_scheduler && /usr/bin/python clear_expire_in_hot.py', 注意用户权限.

删除的内容会记录在当前目录的yyyymm_log_record.record文件中,当做后悔药.

启动

# HTTP API

python sparrow.py

# zmq API

python zmq_scheduler.py &

python zmq_sparrow.py &

数据库设计限制

每个表必须有id字段,且为主键,CURD操作都基于此来识别对象;

冷热库中的表都要有时间线字段,该字段具体名称可通过config.py文件设置(默认为create_time);

未建索引的字段将不能成为条件过滤字段;

组合索引,多个字段间用'__'(双下划线(如: ALTER TABLE user_info ADD INDEX first_name__last_name (first_name, last_name);))来间隔;

查询时,轻库无需指定时间区间. 冷热裤必须指定时间区间, 若不指定,只返回当天的区间结果.

进入冷库的数据即为历史记录. 不支持删\改操作.

HTTP API

插入

curl -X "POST" "http://localhost:5000/oo/login_auth" \

-H "Content-Type: application/json" \

-d "{\"id\":1,\"login_name\":\"fanliang@iqusong.com\",\"password\":\"000000.com\",\"create_time\":0}"

更新

curl -X "PATCH" "http://localhost:5000/oo/login_auth/1" \

-H "Content-Type: application/json" \

-d "{\"password\":\"newpswd\"}"

获取

curl -X "GET" "http://localhost:5000/oo/order_form?filter_str=__order_by__id,__limit__1000,__range__1451197800~1451518200"

删除

curl -X "DELETE" "http://localhost:5000/oo/login_auth/1"

zmq API

RPC

message = dict()

message['action'] = 'RPC'

message['object_name'] = 'order_form'

message['params'] = {

'function': 'generate_id_by', # 支持的方法 'generate_id_by | get_id_of_max_by'

}

socket.send_json(message)

result = socket.recv_json()

result:

{

state: {

code: "200",

zh-cn: "成功",

en-us: "OK"

}

id: 1

}

插入

message = dict()

message['action'] = 'POST'

message['object_name'] = 'order_form'

message['params'] = {

'id': 1,

'create_time': 0,

'finished_time': 0

}

socket.send_json(message)

socket.recv_json()

result:

{

state: {

code: "200",

zh-cn: "成功",

en-us: "OK"

}

}

更新

message = dict()

message['action'] = 'PATCH'

message['object_name'] = 'order_form'

message['params'] = {

'id': 1,

'create_time': 0,

'finished_time': 0

}

socket.send_json(message)

socket.recv_json()

result:

{

state: {

code: "200",

zh-cn: "成功",

en-us: "OK"

}

}

获取

message = dict()

message['action'] = 'GET'

message['object_name'] = 'order_form'

message['params'] = {

'filter_str': '__order_by__id,__limit__1000,__range__1451197800~1451518200'

}

socket.send_json(message)

socket.recv_json()

result:

{

state: {

code: "200",

zh-cn: "成功",

en-us: "OK"

},

list: [

{}

]

}

删除

message = dict()

message['action'] = 'DELETE'

message['object_name'] = 'order_form'

message['params'] = {

'id': 1

}

socket.send_json(message)

socket.recv_json()

result:

{

state: {

code: "200",

zh-cn: "成功",

en-us: "OK"

}

}

filter_str语法

eq

id__eq__100

id等于100的记录

gt

id__gt__100

id大于100的记录

lt

id__lt__100

id小于100的记录

ne

id__ne__100

id不等于100的记录

in

id_in__100~101~103

id等于100或101或103的记录

order_by

__order_by__create_time

依据create_time字段顺序排序

order_by_desc

__order_by_desc__create_time

依据create_time字段倒序排序

limit

__limit__10

限制返回前10条记录

range

__range__1451197800~1451518200

以1451197800~1451518200时间范围限定查找空间

综合示例

__order_by_desc__id,__limit__1000,__range__1451197800~1451518200

依据id字段,倒序返回1451197800~1451518200时间空间中的前1000条记录

id__gt__100,id__lt__1000,name__eq__james

返回id大于100且小于1000的记录中,name等于james的记录

错误码

error_codes = {

'41250': {

'code': '41250',

'zh-cn': u'未支持索引的字段'

},

'50050': {

'code': '50150',

'zh-cn': u'MySQL 链接或执行出错'

},

'50051': {

'code': '50051',

'zh-cn': u'Redis 链接或执行出错'

}

}

FAQ

如何扩大数据库连接限制?

Q: 有两种方式

a. 通过修改配置文件my.cnf

[mysqld]

max_connections = 1000

b. 修改环境变量

SET GLOBAL max_connections = 1000;

python的数据库中间件_sparrow相关推荐

  1. python的数据库中间件_数据库中间件设计方案

    数据库中间件的主要作用是向应用程序开发人员屏蔽读写分离和分库分表面临的挑战,并隐藏底层实现细节,使得开发人员可以像操作单库单表那样去操作数据.在介绍分库分表的主流设计方案前,我们首先回顾一下在单个库的 ...

  2. python写数据库中间件_python3开发进阶-Django框架的中间件的五种用法和逻辑过程...

    阅读目录 一.什么是中间件? 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出. 每个中间件组件都 ...

  3. python写数据库中间件_pythonpostgresql数据库中间件有

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  4. 数据库中间件漫谈——看看云时代,它会走向何方

    来源 | 阿丸笔记 封图| CSDN 下载于视觉中国 前言 随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大:另外,无论怎样升级硬件资源, ...

  5. java中间件是什么意思_数据库中间件漫谈

    1.前言 随着业务的发展,MySQL数据库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作的开销也会越来越大:另外,无论怎样升级硬件资源,单台服务器的资源(CPU.磁盘.内存.网络IO.事 ...

  6. 分布式数据库中间件概念

    2019独角兽企业重金招聘Python工程师标准>>> 从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储.面对分片集群,数据源切换,事务处理,数 ...

  7. 史上最全数据库中间件详解

    导读:本文详细介绍了中间件,主要从数据库拆分过程及挑战.主流数据库中间件设计方案.读写分离核心要点.分库分表核心要点展开说明. 1. 数据库拆分过程及挑战 垂直拆分.读写分离.分库分表(水平拆分).每 ...

  8. Weir:原生 TiDB 支持的数据库中间件

    原文来源: https://tidb.net/blog/bf9f3adc 作者介绍: 徐成选,伴鱼基础架构负责人.后端8年,基础架构6年,传统.互联网行业均有涉猎,曾就职于小米.阿里.初创公司等,目前 ...

  9. 数据库中间件---详解

    一.业务场景 1.当一张表进行水平分库分表之后,可能会影响已有产品功能,同时想要进行多张分表的搜索结果数据聚合在一起,在sql上会比较麻烦(只能不断 join),而且如果不知道分表的表名,业务sql书 ...

最新文章

  1. Python3中__call__方法介绍
  2. iOS应用跳转qq指定联系人聊天
  3. EEPlat的元模型体系
  4. 计算机谭音乐同桌的你,同桌的你_Ava_clover_新浪博客
  5. 正整数和小数的正则写成自定义插件
  6. 为什么自动挡的挡位顺序都是P、R、N、D?
  7. python机器学习-乳腺癌细胞挖掘
  8. 中国移动苏州研发中心前端笔试(1)
  9. Wind River workbench介绍
  10. linux服务器插上u盘不显示,U盘在Linux下显示不正常的解决方法
  11. 2017年统计年鉴在线阅读_我在2017年阅读的内容
  12. 高等数学学习笔记——第三讲——函数的概念与性质(1. 函数的概念)
  13. 爱家Aijiacms高端大型房产门户系统V9源码+带手机端
  14. Michael Jackson Japanese Comic
  15. 网站推广优化教程100条(SEO,网站关键字优化,怎么优化网站,如何优化网站关键字)...
  16. XXTEA加密流程分析
  17. JAVA-IP和手机号归属地查询
  18. BUUCTF之misc 我爱Linux--zhecho的博客csdn
  19. Mycat之——实现MySQL垂直分库
  20. 5gnr信号测试软件,通过锚点站判断5GNR基站的信号电平案例.docx

热门文章

  1. 7-45 海选高大中锋
  2. Android System WebView老版本大全
  3. 【java设计模式系列】3. 抽象工厂模式(Abstract Factory)
  4. 腾讯拟推出个人微信云存储付费服务,你会买单吗?
  5. android设置自动旋转屏幕,android怎样实现关闭系统自动旋转屏幕时能够自动横竖屏...
  6. Ada-GNN: Adapting to Local Patterns for Improving Graph Neural Networks
  7. PHP著名开源项目汇总(LAMP)
  8. 「干货」你必须掌握的 21 个 Java 核心技术
  9. 什么是文案?介绍基本知识和写作技巧
  10. Java8 将List转换为用逗号隔开的字符串