mysql 读写分离(手动和自动方法)
使用sqlalchemy 使mysq自动读写分离:
代码如下:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy, SignallingSession, get_state
from sqlalchemy import orm app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@192.168.105.134:3306/test30' # 设置数据库连接地址
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 是否追踪数据库变化(触发某些钩子函数), 开启后效率会变
app.config['SQLALCHEMY_ECHO'] = True # 开启后, 控制台会打印底层执行的SQL语句 app.config['SQLALCHEMY_BINDS'] = { # get_engine的bind参数为该配置的键
'master': 'mysql://root:mysql@192.168.105.134:3306/test30',
'slave': 'mysql://root:mysql@192.168.105.134:8306/test30'
} class RoutingSession(SignallingSession):
def get_bind(self, mapper=None, clause=None):
"""当进行数据操作时, 会调用该方法来获取进行该操作的数据库引擎(连接)""" state = get_state(self.app)
if self._flushing: # 增删改操作, 使用主库
print('使用主库')
return state.db.get_engine(self.app, bind='master')
else: # 读操作, 使用从库
print('使用从库')
return state.db.get_engine(self.app, bind='slave') class RoutingSQLAlchemy(SQLAlchemy):
def create_session(self, options):
return orm.sessionmaker(class_=RoutingSession, db=self, **options) # 初始化组件(建立数据库连接)
db = RoutingSQLAlchemy(app) # ORM 类->表 类属性->字段 对象->记录
class User(db.Model):
__tablename__ = "t_user" # 设置表名, 默认为类名的小写
id = db.Column(db.Integer, primary_key=True) # 主键
name = db.Column(db.String(20), unique=True, nullable=False) # 设置唯一&非空约束
age = db.Column(db.Integer, default=10, index=True) # 设置默认值约束&建立索引 @app.route('/')
def index():
# 增加数据 进行检验是否读写分离
# 1.创建模型对象
user1 = User(name='zs', age=20)
db.session.add(user1)
db.session.commit() print('-' * 30)
# 查询数据
print(User.query.all())
return "index" if __name__ == '__main__':
db.drop_all() # 删除所有继承自db.Model的表
db.create_all() # 创建所有继承自db.Model的表
app.run(debug=True)
手动时mysql读写分离:
1,修改源码:routing_sqlalchemy.py
import random
from flask_sqlalchemy import SQLAlchemy, BaseQuery, Model, SignallingSession, get_state
from sqlalchemy import orm class Config:
SQLALCHEMY_BINDS = {
"bj_m1": 'mysql://root:mysql@192.168.105.134:3306/test30',
"bj_m2": 'mysql://root:mysql@192.168.105.134:3306/test30',
"bj_s1": 'mysql://root:mysql@192.168.105.134:8306/test30',
"bj_s2": 'mysql://root:mysql@192.168.105.134:8306/test30',
}
SQLALCHEMY_CLUSTER = {
"masters": ["bj_m1", "bj_m2"],
"slaves": ['bj_s1', 'bj_s2'],
"default": 'bj_m1'
}
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = False class RoutingSession(SignallingSession):
def __init__(self, db, autocommit=False, autoflush=True, **options):
SignallingSession.__init__(self, db, autocommit=autocommit, autoflush=autoflush, **options)
self.default_key = db.default_key
self.master_keys = db.master_keys if len(db.master_keys) else self.default_key
self.slave_keys = db.slave_keys if len(db.slave_keys) else self.default_key
self.bind_key = None def get_bind(self, mapper=None, clause=None):
"""获取会话使用的数据库连接engine"""
state = get_state(self.app) if self.bind_key:
# 指定
print('Using DB bind: _name={}'.format(self.bind_key))
return state.db.get_engine(self.app, bind=self.bind_key)
else:
# 默认数据库
print('Using default DB bind: _name={}'.format(self.default_key))
return state.db.get_engine(self.app, bind=self.default_key) def set_to_write(self):
"""使用写数据库"""
self.bind_key = random.choice(self.master_keys) def set_to_read(self):
"""使用读数据库"""
self.bind_key = random.choice(self.slave_keys) class RoutingSQLAlchemy(SQLAlchemy):
def init_app(self, app):
config_binds = app.config.get("SQLALCHEMY_BINDS")
if not config_binds:
raise RuntimeError('Missing SQLALCHEMY_BINDS config') cluster = app.config.get("SQLALCHEMY_CLUSTER")
if not cluster:
raise RuntimeError('Missing SQLALCHEMY_CLUSTER config') default_key = cluster.get('default')
if not default_key:
raise KeyError("deafult is not in SQLALCHEMY_CLUSTER") # 生成并保存数据库引擎
self.master_keys = cluster.get("masters") or []
self.slave_keys = cluster.get("slaves") or []
self.default_key = default_key super(RoutingSQLAlchemy, self).init_app(app) def create_session(self, options):
return orm.sessionmaker(class_=RoutingSession, db=self, **options)
2, __init__.py下导入routing_sqlalchemy.py 中的类创建 db
from .routing_sqlalchemy import RoutingSQLAlchemy db = RoutingSQLAlchemy()
3,定义装饰器类,实现读写分离
import functools from user_select import db def set_read_db(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
db.session().set_to_read()
return f(*args, **kwargs) return wrapper def set_write_db(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
db.session().set_to_write()
return f(*args, **kwargs) return wrapper
4,使用装饰器方式,调用读写分离,如果用装饰器,都使用主库进行读写
from flask import Flask
from user_select import db
from user_select.routing_sqlalchemy import Config
from user_select.decorator import set_read_db, set_write_db app = Flask(__name__)
app.config.from_object(Config) # 初始化数据库连接对象
db.init_app(app) # 建立映射模型 类->表 类属性->字段 对象->记录
class User(db.Model):
__tablename__ = 't_user' # 设置表名 表名默认为类名小写
id = db.Column(db.Integer, primary_key=True) # 主键 默认主键自增
name = db.Column(db.String(20), unique=True) # 设置唯一
age = db.Column(db.Integer) @app.route('/')
@set_write_db
def index():
"""增加数据"""
user1 = User(name='lisi', age=20)
db.session.add(user1)
db.session.commit() return "index" @app.route('/demo1')
# @set_read_db
def demo1():
users = User.query.all()
print(users)
return 'demo1' if __name__ == '__main__':
# db.drop_all() # 删除所有继承自db.Model的表
# db.create_all() # 创建所有继承自db.Model的表
app.run(debug=True)
mysql 读写分离(手动和自动方法)的更多相关文章
- 【转】双机高可用、负载均衡、MySQL(读写分离、主从自动切换)架构设计
架构简介 前几天网友来信说帮忙实现这样一个架构:只有两台机器,需要实现其中一台死机之后另一台能接管这台机器的服务,并且在两台机器正常服务时,两台机器都能用上.于是设计了如下的架构.此架构主要是由kee ...
- 双机高可用、负载均衡、MySQL(读写分离、主从自动切换)架构设计
前几天网友来信说帮忙实现这样一个架构:只有两台机器,需要实现其中一台死机之后另一台能接管这台机器的服务,并且在两台机器正常服务时,两台机器都能用上.于是设计了如下的架构. 架构简介 此架构主要是由ke ...
- 18、mysql读写分离实现的方法
18.1.mysql读写分离实现的方法: 1.通过程序实现读写分离: php和java程序实现读写分离(性能,效率最佳,推荐); php和java程序都可以通过设置多个连接文件轻松实现对数据库的读写分 ...
- MySQL读写分离技术
1.简介 当今MySQL使用相当广泛,随着用户的增多以及数据量的增大,高并发随之而来.然而我们有很多办法可以缓解数据库的压力.分布式数据库.负载均衡.读写分离.增加缓存服务器等等.这里我们将采用读写分 ...
- [记录]MySQL读写分离(Atlas和MySQL-proxy)
MySQL读写分离(Atlas和MySQL-proxy) 一.阿里云使用Atlas从外网访问MySQL(RDS) (同样的方式修改配置文件可以实现代理也可以实现读写分离,具体看使用场景) 1.在跳板机 ...
- 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变
[Mysql主从复制]解决的问题数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了.负载均衡:M ...
- mysql读写分离实战
一个完整的MySQL读写分离环境包括以下几个部分: 应用程序client database proxy database集群 在本次实战中,应用程序client基于c3p0连接后端的database ...
- Mysql-Proxy实现mysql读写分离、负载均衡 (转)
在mysql中实现读写分离.负载均衡,用Mysql-Proxy是很容易的事,不过大型处理对于性能方面还有待提高,主要配置步骤如下: 1.1. mysql-proxy安装 MySQL Proxy就是这么 ...
- 提高性能,MySQL 读写分离环境搭建
这是松哥之前一个零散的笔记,整理出来分享给大伙! MySQL 读写分离在互联网项目中应该算是一个非常常见的需求了.受困于 Linux 和 MySQL 版本问题,很多人经常会搭建失败,今天松哥就给大伙举 ...
随机推荐
- 这道面试必问的JVM面试题70%的Java程序员会做错
前言 聊聊JVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别. JVM可以说和我们是老朋友了 ...
- ueEditor第一次赋值失败
var ue=null; //在初始化富文本的地方 if (ue == null) { ue = new baidu.editor.ui.Editor(); ue.render('inspection ...
- python学习-文件创建读取
# 文件创建 # 读写# 文件存在?不存在?在操作系统上# 读 read r 写 write w# 打开一个文件# fs = open("xiaojian.txt",encodin ...
- leetcode-算法系列-两数之和
本系列的题目都是出自于"leetcode" 用博客记录是为了加强自己的记忆与理解,也希望能和大家交流更好更优的解题思路. 题目: 给定一个整数数组和一个目标值,找出数组中和为目标值 ...
- MySQL的安装、启动和基础配置 —— windows版本
下载 第一步:打开网址,https://www.mysql.com,点击downloads之后跳转到https://www.mysql.com/downloads 第二步 :跳转至网址https:// ...
- 牛客国庆集训派对Day1 L New Game!(堆优化dijkstra+建图)
链接:https://ac.nowcoder.com/acm/contest/201/L来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1048576K,其他语言2097 ...
- 解压小游戏之打砖块(C#+unity)
z这个小游戏很简洁,很简单,非常适合一个人玩,特别减压
- 【CV现状-3.2】纹理与材质
#磨染的初心--计算机视觉的现状 [这一系列文章是关于计算机视觉的反思,希望能引起一些人的共鸣.可以随意传播,随意喷.所涉及的内容过多,将按如下内容划分章节.已经完成的会逐渐加上链接.] 缘起 三维感 ...
- git中的SSL certificate problem: unable to get local issuer certificate错误的解决办法
我们在使用git初始化一个项目时,尤其是通过git submodule update --init --remote初始化子模块时,可能会遇到下面这个错误: fatal: unable to acce ...
- keras 添加L2正则 和 dropout层
在某一层添加L2正则: from keras import regularizer model.add(layers.Dense(..., kernel_regularizer = regulariz ...