wisp / wisp
framework ext lib
Requires
- php: >=5.3.0
- doctrine/dbal: ~2.5
- symfony/cache: >=v4.0
- symfony/console: >=2.8.0
- symfony/yaml: ~2.6
This package is not auto-updated.
Last update: 2024-05-27 05:36:51 UTC
README
- 自动根据配置型分库分表功能
- 目前支持自动缓存功能
外部系统调用示例
设置数据库配置参见
Example\mysql.inc.example.php Example\sharding.inc.example.php
设置配置文件
use Wisp\Config as WispConfig; WispConfig::setDbConfig($dbConfFilePath.'/mysql.inc.php'); WispConfig::setShardingConfig($dbConfFilePath.'/sharding.inc.php');
or
use Wisp\Config; Config::setDbConfig($dbConfFilePath.'/mysql.inc.php'); Config::setShardingConfig($dbConfFilePath.'/sharding.inc.php'); 连接配置还是独立的只是外部能设置配置文件的位置而已
系统依赖
以来 php扩展apcu 作为sharding cache 如果apcu 没有配置则用文件系统缓存 默认换存在tmp下
###start
use Wisp\Config;
#Wisp use Example
notice
1.切分算法不相同的表和库 2. 连表查询目前支持相同切分依赖字段和切分算法的库和表,。
如果用不同的切分算法的表库 目前会取第一个的表切分索引应用于其他表, 所以要注意
后期根据需要提供支持
-
dao 支持事务, 依赖于 statment 依赖于db对应方法的支持
-
基于查询构造的体系暂时部分 构造中 基于orm的 read write throught cache 方案 和延迟写入方案的支持
//use example "repositories":[ { "type":"vcs", "url":"https://github.com/wanghaofu/Wisp.git" } ], "require":{ "king/wisp":"dev-master" }
//config 说明
//使用示例 参见test
示例
生成schema
配置查询
find()
findfirst()
get()
mget()
execute()
## satis and toran
探索库 备份
- "doctrine/shards": "v1.0",
- "yucca/yucca": "@stable",
- "king/core": "dev-master"```
toran satis 自动更新crontab 脚本
*/5 * * * * /www/satis/bin/satis build /www/satis/satis.json /www/satis/web/ */1 * * * * php /www/toran/bin/cron
更新计划
第一次执行
- 生成一个 配置类代码 继承自 生成的基本表结构
- 同时生成一个继承累用于配置 sql语句 配置查询语句完成后再次执行,生成查询类,
- 该类会把查询语句转化成 查询方法及参数,这样方便调用
分库 分表算法
如果吧表分到不同的库中 例子 uuid =10000 db 10000%3=1 table 10000%12 =4 1号库 table 4 1_4
uuid =10001 db 10001%3=2 table 10001%12= 5 2_5
uuid =10002 db 10001%3=0 table 10001%12= 6 0_6
也就是所有的表在每一个库中都必须存在 10000号用户 永远在 1号库表4 10001 在2号库表5 10003 在0好苦 表6
而到底在哪个库是有库的切分算法来定的, 而到地在哪个表是有表切分因子来定的, 那能不能吧 某个表确定到某个固定的库中呢, 这样表和库就建立了关联,
怎么建立关联呢 ,除非表的算法是依据库基础上来的 现在的表分布hash是直接单独生成的, 如果用户定位在 1号库 表是否应该是在1的基础上
v 2.0 分库功能和主从功能
分布实例
example: 607 in:2_5 608 in:3_6 609 in:4_0 610 in:0_1 611 in:1_2 612 in:2_3 613 in:3_4 614 in:4_5 615 in:0_6 616 in:1_0 617 in:2_1 618 in:3_2 619 in:4_3 620 in:0_4
结论 所有的表 在所有库中必须相同的表 就是吧用户数据分布到不同的库和表中,用户的库位置有库算法决定,表位置由表算法 决定, 限定库位置然后定表位置。
`
/**事务的库定位怎么搞 * 在开始事务之前是不知道那个库的, 也是可以知道的,现根据参数 ,和表确定,也就是说必须参数和表 * 这两个参数先单独传过来 ,表这个数据是有的那就剩下 值参数也是有的,这样可以提前确认连接 在执行之前构造连接先要确认大概确认下数据库 * 这个要在 那个缓解确认呢? 获取db的时候! 如果有标和 数据参数 **/ // 在dao的时候需要传递参数 表名和参数 //这里的库名怎么确认 因为连接用的是配置名,而其他地方配置的是库连接主键名
配置优化功能
- 库切分算法和 表切分算法默认配置和 和配置共享支持。
解决方案: 配置成基本类,供调用, 怎么识别是主键配置还是 匿名函数呢? 配置可以独立话存在 ,对库进行默认区分?db_split class 定义然后引用 如果要两种都支持,,那问题就是如果区分两种配置形式。 目前看 ,按照默认配置就ok了 匿名函数就好了 配置同意 ,支持default 值的解决方案 大多数情况下 是可以的
-
单库 不分表 不带从库 的情况下配置实例 单库不分表可以不用配置切分,
-
单库 不分表, 带从库的配置
这种情况 没有测试测试
- 单库分表 带从库
- 多库 不分表 带从库
这种配置 如果从设定必须是和主相同这样会多一个db对象但是连接数是相同的
- 多库 分表 不带从库
这种配置目前没有支持需要完善
- 不带从库的情况 或者从库连接失败的情况
这里分两种情况: 第一种情况,直接连接主库 这种情况已经实现,没有配置从库则选主库!。
第二种 从库连接失败的情况,
从库连接失败的解决方案: 先连接其他从库,如果不存在其他从库 则连接主库。并写下告警日志。 (这个是系统安全行的必要机制,从库挂掉的概率还是很高的,至于主库挂掉,需要运维层面进行处理基于把主库的ip切给备用机器来) 正常连接顺序:
- 如果是查询则自动连接从库, 在连接的时候 随机返回从库配置,这个在dbConfig中实现 ,从库的选择
- 如果从库配置不存在则是主库的配置,就是即使连接设置是从,但是没有从配置,配置返回就是主库
- 如果连接有从库配置,但是从库连接不上,这种情况怎么解决?
- 如果从库连接不上则 首先把该连接配置从配置中去掉,检查有没有其他从库配置,如果有则连接其他从库。 没有连接主库。
这里4 没有实现,这个机制和目前的机制是不同的,需要重新设计才可以支持失败重跳,简单的话就是db初始化 立即连接 如果失败则就可以直接重连,
- 如果cache的连接突然失效怎么处理!? 这种的话好的话也可以用上述机制,目前是没有应对的。
查询规则的机制思考
- 当意图是插入某个主键行 但是主键为空的时候 就会进行全库全表扫描 而且当这个切分键 允许为空的时候 就会出现问题, 就会出现插入成功的问题,和开发者的意图不同了。
- 这种情况怎么解决?
- 解决选项: 提供方法需要全局操作的时候打开全局操作, 否则默认强制只能是带切分操作,如果没有主键则停止业务。 报告错误。
这个方案的优缺点。 不加的话会造成潜在的错误,让有问题的数据插入库,当然可以处理掉
- 当某个连接失效的情况下
异常处理机制 v2.1
- 可以捕获,在statment 如果执行结果为false 则 抛出异常 。 在db会在日志中记下db错误日志,在开启debug情况下会打印到控制台或者浏览器显示
- dao 可以用链式写法进行注册和查询 就是可以用不带主键的方式进行 直接查询设置
example $user->regist("select * from user where uuid = :uuid ")
->find([uuid=>234234]); 这种方式用来补充 配置方式的不便捷对于快速开发测试 的一个有效补充
feature/easyBuild
这个版本倾向与单独的 通过查询构造器来进行剩余业务的 访问层
之前dao的查询注册形式 保留 , 跨库访问的方式整分离出来 find的实现也给成 查询构造这边的适配
查询用查询构造器 以及 注册机制
修改也用查询构造器 和模型混合的方式
添加用模型对象 直接保存的方式
除了模型之外 其他的所有成员变量都必须是私有的或者protected 的 方便识别 仅开放先练的 成员方法。或者所有的成员方法家 前加q 例如 qfind qsave qcommit qbegin q
基于构造器 查询对象的用法说明
`
UPDATE app SET
app_id
= :v_0,app_key
= :v_1 WHEREname
= :p_0 [:p_0] => xx [:v_0] => 34 [:v_1] => f52854cc99ae1c1966b0a21d0127975b
INSERT INTO app (
name
) VALUES (:v_0)
Array ( [:v_0] => asdfasd ) `
SELECT * FROM WHERE
name
= :p_0 ANDname
= :p_1 Array ( [:p_0] => to [:p_1] => hh )
. 如上 p 开头的是 查询部分条件的参数 由 eq 类的查询构造产生, 直邮在查询修改删除的时候 构造条件会生成,有查询构造器生成 . v 打头的是 修改 和添加的时候 参数部分 会由 对象结构带出 . reg 写的完整构造的形式 不按照这个规则走
切分字段策略
. 专门保存
dao 模式问题的几个问题 第一个: statment 形式中有 find这个参数的控制 对这里有什么影响 这里limit 是可以直接设置的 , 没什么影响 这边的东西可以直接吧limit带到语句中所以是ok的 find那边是兼容的
但是find是子级 查询构造器是是 父级如果 依赖于find的化 需要吧 查询构造器 的多数方法 降到和dao同级的位置这样方便调用!
###dao gets 参数问题
gets本身传过来的参数 为数组形式的 imodules 形式的 以及直线对象过早形式的
当where条件 显示制定的时候 如果都是字段是可以用model形式的 。如果制定字端具有超出model外的条件字段的化 就必须用数组行时 或者说必须让支持增加而外的成员对象能力
这个时候在查询的时候是不能对字段进行重新 定义repare 变量名称的
easybuild 版本说明
几本注册方式
. register app::cascade()->register("select * from xx where name = :name", 'key', 30); ->find('key',['name'=>'test']);
module::cascade()->gets();
get module::cascade()->limit(1)->get();
切分参数的设计说明
方案1
1: 提供设置参数 主动设置 2: 提供清理参数主动清理 3: 没有主动清理的默认保留 4: 没有主动设置的 不自动通过params 参数获取)
增强方案2
1: 处理参数时候显示的 根据配置 直接赋值 (方案1是从一堆参数重找出切分参数) 2:
3: 查询 插入 修改 删除 完了之后必须保证 df本身也被清理 所有数据保存在cascade中 等下一次再传入df的时候 再次更新 cascade
问题: 清除df会有什么影响? 1.下一次再次访问的时候 df中的数据都消失了 会取 ca中存在的 全部改掉就行了 2.再次查询用到 这些关键信息的时候 怎么弄? 从dao中取 是存在的 3. 等再次插入df的时候 ,是不是ca里的三大信息就更新了 这个规则怎么定。 需要明确。否则含糊不清
出了 三大关键信息之外 其他的都会重新构建 也会取到
规则: 通过对象初始化的成员不允许 更新 三大信息 ,要查询独立简历入口对象 不要让入口对象通用 Example: a1::cascade()->insert();
a2::cascade()->gets();
应该禁止掉 a2 插入a1 的内容 插入的话容易引起理解混乱
cascade()->insert($a1);
// chaxun $a1 = A1::Cascade(); $a1->gets()
// 修改 $am->xx=1; $a1->update($am);
// 这两个容易引起混乱 影响范围 插入修改删除
// 自动切分参数的获取 和主动设定 1:自动参数的获取需要 支持 兼容老版本
2:主动设定的需要规则支持