关于 Buffered Query 和 Unbuffered Query:http://www.php.net/manual/zh/mysqlinfo.concepts.buffering.php

对于结果集小的查询,一般就开启 Buffered Query 一次取回(fetchAll);

对于结果集很大的查询,可以开启 Unbuffered Query 来遍历资源一条条 fetch,避免撑爆客户端内存;

PDO 属性设置:http://php.net/manual/zh/pdo.setattribute.php

其它解决方案:

1. 高频投递(依赖进程数),少量处理(每批次数据),可以自己用 Process 实现进程池处理队列任务,或者使用自带的 task 功能。

2. 使用自带 task 功能的情况下,如果 worker 不需要与 task worker 通讯,那么 onTask 不要使用 return 返回数据,减少消耗。

3. worker 使用 task( ) 投递频率必须小于 task 进程数(task_worker_num),可以程序来限制。

  比方说 $taskWorkerNum 是 50,

  任务投递次数累加 $deliverNo,

  onTask 内完成任务时计数 $serv->atomic->add(1),

  完成任务数 $serv->atomic->get() 获得。

  那么在投递之后需要进行判断,投递总数 - 完成数 >= 任务进程数,说明投递次数满了,暂停一会儿,保证 task 进程不是满负荷工作。

/**
* 调度工作
* https://cnblogs.com/farwish
*/
public function onWorkerStart(\Swoole\Server $server, $workerId)
{
if ($workerId == 0) {
$data = [1, 2, 3]; foreach ($data as $item) {
// 限流与投递
while (($server->deliverNo - $server->atomic->get()) >= $this->taskWorker) {
echo "等待空闲 task 进程\n";
sleep(1);
}
$server->task($item);
$server->deliverNo++;
} // 任务结束后退出 server
while (true) {
if ($server->deliverNo == $server->atomic->get()) {
$server->shutdown();
}
sleep(1);
}
}
}

服务初始化部分:

    public function initTaskServer()
{
$server = new \Swoole\Server('0.0.0.0'); $server->atomic = new \Swoole\Atomic(0);
$server->deliverNo = 0; $server->set([
'worker_num' => 1,
'task_worker_num' => $this->taskWorkerNum,
'task_ipc_mode' => 1,
'task_max_request' => 5000,
]); $server->on('workerStart', [$this, 'onWorkerStart']);
$server->on('task', [$this, 'onTask']);
$server->on('receive', [$this, 'onReceive']);
$server->on('finish', [$this, 'onFinish']); $server->start();
} protected function onWorkerStart(Server $server, $workerId)
{
} protected function onTask(Server $server, $taskId, $fromId, $data)
{
} protected function onReceive(Server $server, $fd, $reactorId, $data)
{
} protected function onFinish(Server $server, $taskId, $data)
{
}

4. 不使用 server 和 task 多进程的情况,利用 swoole 协程中的 channel 实现 producer、consumer 模式,生产者 unbuffer query 持续 push 数据到通道,消费者持续 pop 消费;生产者没有数据时可退出,消费者检测到生产者退出后也随即退出。

缺点是在复杂场景下(比如多层查询再加循环处理),编程会比较困难,比如:等待所有子协程结束的功能(WaitGroup)、多 consumer 的场景,需要自己封装很多组件。

其它:

多进程、多协程的情况下,需要配合使用数据库连接池,因为数据库并发连接数资源有限。

多进程只是利用到了多核,计算密集型场景有优势;协程并发相比更轻量,单进程内利用I/O切换实现并发,适合IO密集型场景。

Course:http://www.yzmedu.com/course/330

Docs:https://wiki.swoole.com/wiki/page/481.html

Link:https://www.cnblogs.com/farwish/p/10242294.html

[Sw] 使用 Swoole Server task/协程 处理大数据量异步任务时注意的更多相关文章

  1. Python之路-python(Queue队列、进程、Gevent协程、Select\Poll\Epoll异步IO与事件驱动)

    一.进程: 1.语法 2.进程间通讯 3.进程池 二.Gevent协程 三.Select\Poll\Epoll异步IO与事件驱动 一.进程: 1.语法 简单的启动线程语法 def run(name): ...

  2. [转]向facebook学习,通过协程实现mysql查询的异步化

    FROM : 通过协程实现mysql查询的异步化 前言 最近学习了赵海平的演讲,了解到facebook的mysql查询可以进行异步化,从而提高性能.由于facebook实现的比较早,他们不得不对php ...

  3. Python3的原生协程(Async/Await)和Tornado异步非阻塞

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_113 我们知道在程序在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞,而协程作为一种用户态的轻量级线程,可以帮我们解决 ...

  4. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  5. C# & SQL Server大数据量插入方式对比

    以下内容大部分来自: http://blog.csdn.net/tjvictor/article/details/4360030 部分内容出自互联网,实验结果为亲测. 最近自己开发一个向数据库中插入大 ...

  6. sql server 2005 大数据量插入性能对比

    sql server 2005大数据量的插入操作 第一,写个存储过程,传入参数,存储过程里面是insert操作, 第二,用System.Data.SqlClient.SqlBulkCopy实例方法, ...

  7. 大数据量下的SQL Server数据库自身优化

    原文: http://www.d1net.com/bigdata/news/284983.html 1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情 ...

  8. [转]Sql server 大数据量分页存储过程效率测试附代码

    本文转自:http://www.cnblogs.com/lli0077/archive/2008/09/03/1282862.html 在项目中,我们经常遇到或用到分页,那么在大数据量(百万级以上)下 ...

  9. 【SQL server初级】数据库性能优化一:数据库自身优化(大数据量)

    数据库优化包含以下三部分,数据库自身的优化,数据库表优化,程序操作优化.此文为第一部分 数据库性能优化一:数据库自身优化 优化①:增加次数据文件,设置文件自动增长(粗略数据分区) 1.1:增加次数据文 ...

随机推荐

  1. [JAVA]JAVA实现多线程的三种方式

    1.继承Thread类,通过start()方法调用 public class MultiThreadByExtends extends Thread { @Override public void r ...

  2. layui:数据表格如何合并单元格

    layui.use('table', function () { var table = layui.table; table.render({ elem: '#applyTab' , url: '$ ...

  3. 收藏品:MP3播放器

    大三下学期的时候,有一段生活激情似火. 那时候,我在外边接了项目,把宿舍的哥们儿都组织了起来,一起开发赚钱.我们在小区里租了房子,又多借了一台电脑,哥几个轮流上阵写代码.准备考研的兄弟也帮手做饭,我和 ...

  4. 利用Clang(Python接口)来解析C++

    1 背景说明 最近希望利用开源库来解析C++头文件,并做一些自动翻译.自动注释之类的工作.经过两天的调研,发现clang最有希望满足需求.clang提供了三套接口来共外部使用,liblang最适合作为 ...

  5. hive 的map数和reduce如何确定(转)

    转自博客:https://blog.csdn.net/u013385925/article/details/78245011(没找到原创者,该博客也是转发)   一.    控制hive任务中的map ...

  6. Asynchronous programming in javascript

    Javascript是单线程的,因此异步编程对其尤为重要. ES 6以前: * 回调函数* 事件监听(事件发布/订阅)* Promise对象 ES 6: * Generator函数(协程corouti ...

  7. ORACLE 数据库使用正则表达式重新计算指定位置的数字为新的数字

    昨天工作中遇到这个问题: 有一个这样的字符串expression变量,里面可能存储的值类似于以下[Index_CivilWork,0]*(1+[Y10814,1])/[Y10674,1] [300,1 ...

  8. Azkaban实战,Command类型单一job示例,任务中执行外部shell脚本,Command类型多job工作flow,HDFS操作任务,MapReduce任务,HIVE任务

    本文转载自:https://blog.csdn.net/tototuzuoquan/article/details/73251616 1.Azkaban实战 Azkaba内置的任务类型支持comman ...

  9. 操作系统实现线程的几种模式 和 java创建线程的3个方式

    操作系统实现线程的几种模式 和 java创建线程的3个方式  这是两个概念 在操作系统中,线程可以实现在用户模式下,也可以实现在内核模式下,也可以两者结合实现. 1.实现线程的三种方式: (1)继承t ...

  10. excle删除重复项的行,自定义删除第几个

    在B1输入 =COUNTIF(A$1:A1,A1) 下拉,会有数字1.2.1.2 第二步,选中B列升序排序,排序后,将B列为1的整行删除即可. 再补充下,这样是以姓名为条件来筛选,不会影响你的数据.你 ...