2 CHN 08 4 数据库 FastDbClient
Rickiewars edited this page 2023-04-12 17:23:04 +02:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

English | 简体中文

顾名思义FastDbClient会提供比普通的DbClient更高的性能。与DbClient拥有自己的EventLoop不同它和Web应用的网络IO线程和主线程共用 EventLoop这使得FastDbClient的内部实现可以采用无锁的方式进行因而会更高效。

经测试极限高负载条件下FastDbClient比DbClient有10%到20%的性能提升。

创建和获取

FastDbClient必须由框架使用框架的接口或通过配置文件创建使用框架的createDbClient接口当最后一个参数为true时即可创建一个FastDbClient对象。

配置文件中的每个db_client配置项下有个is_fast子选项该选项为true时表明该对象是FastDbClient。

框架会针对每个IO事件循环和主事件循环创建单独的FastDbClient每个FastDbClient内部管理数个数据库连接。IO事件循环数由框架的"threads_num"选择控制一般设为主机的CPU核心数每个事件循环管理的数据库连接数由数据库客户端的"connection_number"选项控制所以一项FastDbClient的总连接数为(threads_num+1) * connection_number,参考配置文件

FastDbClient的获取接口和普通DbClient的类似如下

orm::DbClientPtr getFastDbClient(const std::string &name = "default");
/// 使用drogon::app().getFastDbClient("clientName")调用

需要指出的是由于FastDbClient的特殊性用户必须在IO事件循环线程或主线程内调用上述接口才能得到正确的智能指针在其它线程只能获得空指针无法使用。

使用

FastDbClient的使用与普通的DbClient几乎完全一致除了下面这些限制高性能的代价是使用上有约束这是可以理解的

  • 获取和使用都必须在框架的IO事件循环线程或主线程内在其它线程获取FastDbClient只能得到空指针在其它线程使用它会有无法预料的错误因为无锁的条件遭到破坏好在用户在应用编程的多数地方都是在IO线程内比如各种控制器的处理函数内过滤器的过滤函数内。容易知道FastDbClient接口的各种回调函数内也是在当前IO线程可以放心嵌套使用。
  • 永远不要使用FastDbClient的阻塞接口因为这种接口会阻塞当前线程而当前线程也是处理这个对象的数据库IO的线程这会造成永久的阻塞用户没有机会拿到结果。
  • 同步的事务创建接口是有可能阻塞的所有连接都忙的时候所以FastDbClient的同步事务创建接口直接返回空指针如果要在FastDbClient上使用事务请使用异步的事务创建接口。
  • 使用FastDbClient创建Orm的Mapper对象后使用时也要注意只能使用异步非阻塞接口。

08.5 自动批处理