Squeryl - HikariCP - mySql - 将读取流量分配给从站
Posted
技术标签:
【中文标题】Squeryl - HikariCP - mySql - 将读取流量分配给从站【英文标题】:Squeryl - HikariCP - mySql - Distributing Read Traffic to Slaves 【发布时间】:2015-06-06 03:40:42 【问题描述】:我正在尝试按照http://dev.mysql.com/doc/connector-j/en/connector-j-master-slave-replication-connection.html 中列出的步骤进行操作
要启用此功能,请使用 com.mysql.jdbc.ReplicationDriver 配置应用服务器的连接池时的类
来自https://github.com/brettwooldridge/HikariCP - 它说
HikariCP 将尝试通过 DriverManager 解析驱动程序 完全基于 jdbcUrl
那么这个配置就足够了吗?
db.default.url=jdbc:mysql:replication ...
Squeryl 有许多 db Adapters;但我的理解是这些无关吗? http://squeryl.org/api/index.html#org.squeryl.adapters.MySQLInnoDBAdapter
抱歉加载了关键字 - 我只是不太确定我需要关注哪里
谢谢 布伦特
【问题讨论】:
【参考方案1】:对于 2020 年达到此目标的人,Hikari 使用
com.mysql.jdbc.jdbc2.optional.MysqlDataSource
作为数据源。如果我看一下上面类的代码。它有一个名为 connect 的方法,该方法返回 Connection 实例。
protected Connection getConnection(Properties props) throws SQLException
String jdbcUrlToUse = null;
if (!this.explicitUrl)
StringBuffer jdbcUrl = new StringBuffer("jdbc:mysql://");
if (this.hostName != null)
jdbcUrl.append(this.hostName);
jdbcUrl.append(":");
jdbcUrl.append(this.port);
jdbcUrl.append("/");
if (this.databaseName != null)
jdbcUrl.append(this.databaseName);
jdbcUrlToUse = jdbcUrl.toString();
else
jdbcUrlToUse = this.url;
Properties urlProps = mysqlDriver.parseURL(jdbcUrlToUse, (Properties)null);
urlProps.remove("DBNAME");
urlProps.remove("HOST");
urlProps.remove("PORT");
Iterator keys = urlProps.keySet().iterator();
while(keys.hasNext())
String key = (String)keys.next();
props.setProperty(key, urlProps.getProperty(key));
return mysqlDriver.connect(jdbcUrlToUse, props);
其中mysqlDriver是
的一个实例protected static final NonRegisteringDriver mysqlDriver;
如果我检查 NonRegisteringDriver 类的连接方法。看起来是这样的
public Connection connect(String url, Properties info) throws SQLException
if (url != null)
if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:loadbalance://"))
return this.connectLoadBalanced(url, info);
if (StringUtils.startsWithIgnoreCase(url, "jdbc:mysql:replication://"))
return this.connectReplicationConnection(url, info);
Properties props = null;
if ((props = this.parseURL(url, info)) == null)
return null;
else if (!"1".equals(props.getProperty("NUM_HOSTS")))
return this.connectFailover(url, info);
else
try
com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url);
return newConn;
catch (SQLException var6)
throw var6;
catch (Exception var7)
SQLException sqlEx = SQLError.createSQLException(Messages.getString("NonRegisteringDriver.17") + var7.toString() + Messages.getString("NonRegisteringDriver.18"), "08001", (ExceptionInterceptor)null);
sqlEx.initCause(var7);
throw sqlEx;
看了代码,貌似支持。直到现在我还没有尝试过。将尝试从个人经验中让您知道。从代码看,直接可行。
【讨论】:
【参考方案2】:Squeryl 提供不同的 MySQL 适配器,因为 innodb 支持引用键,而 myisam 不支持。看来您所做的事情应该在连接池级别处理,所以我认为您的 Squeryl 配置不会产生影响。
我从来没有为复制的 MySQL 配置 Hikari,但如果它需要一个替代的 JDBC 驱动程序,如果你能提供一个 JDBC URL 并且一切正常,我会感到惊讶。我猜 Hikari 的默认功能是选择普通的 MySQL JDBC 驱动程序,除非你另有说明。幸运的是,Hikari 有很多 config options,包括设置特定 driverClassName
的能力。
【讨论】:
HikariCP 2.3.6 刚刚发布,并且包含一个错误修复,用于在指定driverClassName
时查找特定驱动程序。以前的行为是始终使用基于 URL 的解析。尽管如此,查看 MySQL 代码,似乎 MySQL 仍然应该自动注册 ReplicationDriver(并且基于 URL 的解析应该可以工作)。【参考方案3】:
复制允许使用不同的 URL:
jdbc:mysql:replication://[server1],[server2],[server2]/[database]
我从未尝试过,但我认为这将解决 ReplicationDriver。
【讨论】:
【参考方案4】:我发现自己回到了这里 - 请注意,hikari 不支持复制驱动程序。
https://github.com/brettwooldridge/HikariCP/issues/625#issuecomment-251613688
MySQL Replication Driver simply does NOT work together with HikariCP.
和
https://groups.google.com/forum/#!msg/hikari-cp/KtKgzR8COrE/higEHoPkAwAJ
... nobody running anything resembling a mission critical application takes MySQL's driver-level replication support seriously.
【讨论】:
以上是关于Squeryl - HikariCP - mySql - 将读取流量分配给从站的主要内容,如果未能解决你的问题,请参考以下文章