就不再长篇大论了… 我相信很多朋友都在使用ORM库来代替繁杂的原生的sql语句。 但如果有特需一点的需求,比如要主从分离? 我们以前的做法很是暴力,直接修改peewee的源码,当他在调用select相关函数的时候,会重置一个mysql db连接,当然是改成从库。 近期才发现peewee的BaseModel有read_slaves参数….
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.
除了上面乱改代码之外,还有这些….. 因为业务有大量的分库分表存在,这样导致一个现象,我们要输出N个表对象,我不能忍这个,所以改代码。 我们是在python peewee里加了一个patch组件,绕过了几个逻辑。 原理倒是简单,其实主要难度在于读懂peewee的源码。 当每次初始化程序的时候会从redis获取最新的分库分表配置信息,大多是通过id和时间区间来分表。 这peewee的改造工程是不小的, 找个时间专门给大家讲述一下。按我的经验来说,每个语言的web框架都是该语言的精华,里面有各种的语法糖,黑魔法的使用 。
言归正传 我们还是继续聊peewee的读写分离。 直接看源码… 这个是peewee实现主从读写分离的主要功能类,原理就是继承modol,重写了select和raw函数…. 另外通过_get_read_database来RR轮训的方式来获取从mysql连接对象。
#xiaorui.cc class ReadSlaveModel(Model): @classmethod def _get_read_database(cls): if not getattr(cls._meta, 'read_slaves', None): return cls._meta.database current_idx = getattr(cls, '_read_slave_idx', -1) cls._read_slave_idx = (current_idx + 1) % len(cls._meta.read_slaves) return cls._meta.read_slaves[cls._read_slave_idx] @classmethod def select(cls, *args, **kwargs): query = super(ReadSlaveModel, cls).select(*args, **kwargs) query.database = cls._get_read_database() return query @classmethod def raw(cls, *args, **kwargs): query = super(ReadSlaveModel, cls).raw(*args, **kwargs) if query._sql.lower().startswith('select'): query.database = cls._get_read_database() return query
这个peewee的主从使用方法很简单,毕竟都封装差不多了,对于你我来说,只管用就可以了。 也就我是我闲着没事总想看看人家源码是怎么实现的,O(∩_∩)O~….
from config import MYSQL_CONF master = MySQLDatabase('buzz_master', **MYSQL_CONF) read_db = MySQLDatabase('buzz_master', **MYSQL_CONF) read_db2 = MySQLDatabase('buzz_master', **MYSQL_CONF) from playhouse.pool import PooledMySQLDatabase db = PooledMySQLDatabase( database='buzz_master', max_connections=16, stale_timeout=600,**MYSQL_CONF) class BaseModel(Model): class Meta: database = master read_slaves = [read_db,read_db2]
这样就完事了… peewee的select都会从 从mysql 取数据。 如果你有一些原因导致你要从master取数据,那么可以使用SelectQuery方法。
现在mysql分库分表的读写逻辑,大多数公司都是放在proxy层面来实现的,因为能更好的统一入库,对于大多数程序来说,他只关心纯业务就可以了。 但也有些公司例外,比如唯品会, 蘑菇街,他们是在本程序里面实现的分库分表。 作为程序员我更喜欢第一种,因为我省事了。
但我也知道当前开源的mysql代理没几个太靠谱的,像mycat,功能很丰富,但性能不咋地…. 像mysql proxy ,性能和功能都是个渣, 像陈非的kingshard,我暂时还不敢用,虽然我曾经给kingshard捐过钱….
peewee 跟 django 的orm框架部分 是不是差不多