어제 Liao Xuefeng의 블로그에서 컴퓨팅 집약적 vs. IO 집약적에 대한 장을 읽었습니다. 발췌 내용은 다음과 같습니다.
작업을 컴퓨팅 집약적 작업과 IO 집약적 작업으로 나눌 수 있습니다.
컴퓨팅 집약적 작업은 파이 계산, 비디오의 고화질 디코딩 등 많은 양의 계산이 필요하고 CPU 리소스를 소비하는 것이 특징이며 모두 CPU의 컴퓨팅 성능에 의존합니다. 이러한 컴퓨팅 집약적인 작업은 멀티 태스킹으로도 완료할 수 있지만 작업이 많을수록 작업 전환에 더 많은 시간이 소요되고 작업 실행 시 CPU의 효율성이 낮아집니다. CPU 사용, 컴퓨팅 집약적인 작업 동시 작업 수는 CPU 코어 수와 동일해야 합니다.
컴퓨팅 집약적인 작업은 주로 CPU 리소스를 소비하므로 코드 실행 효율성이 중요합니다. Python과 같은 스크립팅 언어는 매우 비효율적으로 실행되며 계산 집약적인 작업에는 전혀 적합하지 않습니다. 계산 집약적인 작업의 경우 C 언어로 작성하는 것이 좋습니다.
IO 집약적, 네트워크 및 디스크 IO와 관련된 작업은 모두 IO 집약적인 작업입니다. 이러한 유형의 작업의 특징은 CPU 소비가 매우 적고 대부분의 시간 동안 작업이 IO 작업을 기다리고 있다는 것입니다. 완료(IO 속도가 CPU 및 메모리 속도보다 훨씬 낮기 때문). IO 집약적인 작업의 경우 작업이 많을수록 CPU 효율성은 높아지지만 한계가 있습니다. 가장 일반적인 작업은 웹 애플리케이션과 같은 IO 집약적인 작업입니다.
IO 집약적인 작업을 실행하는 동안 99%의 시간이 IO에 소요되고 CPU에 소요되는 시간은 거의 없습니다. 따라서 Python과 같이 매우 느린 스크립트 언어를 매우 빠른 C 언어로 교체하는 것은 완전히 운영 효율성입니다. 개선될 수 없습니다. IO 집약적인 작업의 경우 가장 적합한 언어는 개발 효율성이 가장 높은(코드 양이 가장 적은) 언어가 첫 번째 선택이고 C 언어는 최악입니다.
식사하러 식당에 가면, 식당의 웨이터가 주문을 받은 후 바로 주방에 메뉴를 건네주고, 주방에서 기다리지 않고 바로 다음 손님에게로 갑니다(블로킹) 코드>). 요리가 끝날 때까지 셰프가 “음식 가져와”라고 외친다(이벤트). 웨이터가 주방으로 달려가 접시를 테이블로 가져옵니다(이벤트 처리/콜백)
이 밤에서 우리는 웨이터가 CPU에 해당하고, 주방의 업무가 I/O에 해당한다고 간단히 이해할 수 있습니다. 분명히 레스토랑에서 웨이터의 일은 복잡하지 않습니다. 대부분의 "음식을 기다리는 시간"은 "주방을 기다리는 시간"입니다. 이는 오늘날 대부분의 웹사이트의 상황과 유사합니다. 웹사이트는 일반적으로 너무 많은 복잡한 작업을 수행할 필요가 없지만 사진 및 비디오 읽기와 같은 데이터베이스 쿼리와 같은 I/O 처리를 기다리는 데 많은 시간을 소비해야 합니다. . 🎜
🎜그래서 Node.js는 기존 웹 서비스에서 "요청이 올 때마다 스레드를 열어 별도의 처리를 수행하는" 방식을 버리고 대신 기본적으로 단일 스레드만 높은 부담을 감당할 수 있는 모델을 채택했습니다. 동시성의. 🎜
🎜이러한 상황에서는 Node.js가 IO 집약적인 작업 처리에 더 적합합니다라고 말합니다. 🎜
🎜하지만 예를 들어 위의 밤을 바꾸면 식당이 아니라 은행을 열게 됩니다. 고객이 찾아와 일정 금액을 인출해 달라고 할 때마다 웨이터로서 고객의 계좌 레벨에 따라 이자율, 이자, 배당금 등을 계산해야 하는데... (임의의 비유는 아닐 수도 있음) 해당), "돈을 인출한다" 그리고 고객에게 넘겨준다" 이 동작 자체는 복잡하지 않습니다. 🎜
🎜현재로서는 각 요청마다 웨이터의 시간이 많이 필요하기 때문에 (필연 차단) 웨이터 한 명만으로는 레스토랑처럼 많은 수의 고객을 처리할 수 있다고 기대할 수 없습니다. 현재로서는 PHP와 같은 전통적인 모델이 더 적합해질 수 있습니다. 🎜
🎜위 내용을 통해 귀하의 혼란이 해소되기를 바랍니다🎜
계산 집약적인 것은 무엇입니까? 예를 들어 SQLite 데이터베이스를 Linux 메모리 파일 시스템 /dev/shm에 배치하여 100만 개의 데이터에 대해 SELECT 쿼리 작업을 수행하면 B+ 트리 인덱스를 사용할 때 이 SELECT 쿼리가 실행됩니다. B+ 트리 인덱스에 대한 이진 검색은 인덱스를 사용하지 않는 경우 단순히 전체 테이블을 검색하는 것도 집약적인 계산이므로 관계형 데이터베이스와 같은 것들은 일반적으로 성능 보장 및 메모리 제어를 사용하여 구현됩니다. .
IO 집약적이란 무엇입니까? 예를 들어, SQLite 데이터베이스는 메모리에 없지만 일반 기계 디스크에서는 쓰기 작업(INSERT/UPDATE/DELETE)이 일반적인 IO 집약적 작업입니다. 왜냐하면 현재 CPU 속도가 아무리 빠르더라도 마찬가지이기 때문입니다. , SQLite 엔진은 더 빠르며 기계식 디스크의 쓰기 작업으로 인해 속도도 느려집니다. 따라서 동시성을 위해 SQLite는 나중에 WAL(write-ahead log) 쓰기를 도입했습니다. 특정 구성은 SQLite 쿼리를 실행하는 것입니다. WAL(write-ahead log)预写式日志支持,具体配置就是执行一下SQLite查询:
WAL 메커니즘의 원칙은 수정 사항이 데이터베이스 파일에 직접 기록되지 않고 WAL(data.db3-wal)이라는 다른 파일에 기록된다는 것입니다. 트랜잭션이 실패하면 WAL의 레코드가 무시되고 수정이 취소됩니다. 트랜잭션이 성공하면 나중에 데이터베이스 파일에 다시 기록되고(PRAGMA 동기 = NORMAL) 수정을 커밋합니다. WAL 파일과 데이터베이스 파일을 동기화하는 동작을 체크포인트에 의해 자동으로 실행됩니다. SQLite는 WAL 파일이 1000페이지의 수정 사항을 누적하는 경우입니다(PRAGMA wal_autocheckpoint). 적절한 시점에 수동으로 체크포인트를 실행할 수도 있습니다. SQLite는 PRAGMA wal_checkpoint를 실행한 후 WAL 파일이 비어 있게 됩니다. 읽기를 수행하면 SQLite는 WAL 파일을 검색하여 마지막 쓰기 지점을 찾아 기억하고 이후 쓰기 지점을 무시합니다(이렇게 하면 읽기와 쓰기가 병렬로 수행될 수 있음). 이어서 데이터를 저장할 페이지를 결정합니다. WAL 파일에 있으면 WAL 파일에 있는 데이터를 읽습니다. 그렇지 않으면 데이터베이스 파일에 있는 데이터를 직접 읽습니다. 쓰기 시 SQLite는 이를 WAL 파일에 쓸 수 있습니다. 쓰기가 보장되어야 하므로 쓰기와 쓰기가 동시에 실행될 수 없습니다. WAL 구현 중에는 공유 메모리 기술(data.db3-shm)이 사용되므로 모든 읽기 및 쓰기 프로세스가 동일한 머신에서 이루어져야 합니다. 데이터 일관성은 보장할 수 없습니다.
WAL 및 체크포인트와 같은 개념은 MySQL과 같은 다른 데이터베이스에도 존재하지만 MySQL은 더 복잡하고 WAL+checkpoint 메서드와 같은 대규모 동시 쓰기 작업을 지원할 수 있다고 생각하면 됩니다. 비동기식 글쓰기.🎜
🎜Node의 JS 인터프리터는 Chromium의 V8을 기반으로 하며 V8에는 JIT JIT 컴파일 메커니즘이 있으므로 Node의 집약적 컴퓨팅 성능은 PHP보다 낮습니다. PHP 관계자가 현재 PHP의 JIT 테스트를 개발하고 있지만 성능은 여전히 좋지 않습니다. V8. 그러나 Node가 좋은 컴퓨팅 성능을 갖고 있다고 해도 Node에서 대규모 집약적 계산을 수행하는 것을 권장하는 사람은 거의 없습니다. 왜냐하면 집약적인 컴퓨팅 소비로 인해 필연적으로 Node 서비스가 차단될 것이기 때문입니다. 이는 Node가 주장하는 비차단 개념에 어긋납니다.🎜
Node는 JS의 이벤트 중심 특성을 사용하여 논블로킹을 달성하지만 콜백 기반 이벤트 프로그래밍 방법은 코드 유지 관리에 도움이 되지 않습니다. 또한 Node와 같은 서비스는 Java와 같은 단일 프로세스, 멀티스레딩 및 멀티 코어를 사용할 수 없습니다. Tomcat과 같은 서비스, V8은 그렇지 않습니다. 멀티스레딩용으로 설계되지 않았기 때문에 Node 관계자는 멀티코어를 활용하기 위해 클러스터 다중 프로세스 모듈만 구축할 수 있습니다.
PHP는 상대적으로 평범하고 계산 속도가 JIT 언어만큼 빠르지는 않습니다. 그러나 JIT가 아닌 일반 스크립트 언어 중에서는 PHP가 느리지 않습니다. 예를 들어 PHP5는 이미 Python보다 빠르며 PHP7은 훨씬 빠릅니다. php-src 같은 Python보다 /Zend/bench.php 테스트에서 PHP 7.1의 시간 소모는 5.4의 1/4에 불과합니다.
또한 PHP의 PHP-FPM 및 Apache MOD_PHP와 같은 다중 프로세스 FastCGI 실행 방법은 다중 코어를 쉽게 활용할 수 있습니다. 또한 opcache를 활성화하여 PHP 스크립트의 opcode를 공유 메모리에 캐시할 수도 있습니다. function.php의 많은 기능은 opcache가 메모리에 스크립트를 캐시한 후에 PHP가 요청될 때마다 스크립트를 다시 구문 분석할 필요가 없으며 opcode를 직접 실행할 수 있으며 특히 복잡한 경우 성능 향상이 매우 분명합니다. PHP 애플리케이션.
어제 Liao Xuefeng의 블로그에서 컴퓨팅 집약적 vs. IO 집약적에 대한 장을 읽었습니다. 발췌 내용은 다음과 같습니다.
Node.js 언어의
비차단
및이벤트 기반
개념을 설명하는 잘 사용되는 밤이 있는데 대략 다음과 같습니다.非阻塞
,事件驱动
概念,大约是这样的:在这个栗子中,我们可以简单的理解为:服务员相当于
CPU
,而厨房的工作就是I/O
。显然的,在一个饭店里,服务员的工作并不复杂,”等待上菜的时间“多数是花在”等待厨房“上。这与如今大多数网站的情况相似:网站通常不需要做太多复杂的运算,但需要花费大量的时间等待 I/O 处理,比如数据库查询,比如图片、视频的读取。于是 Node.js 舍弃了传统 Web 服务中“每当一次请求来临,都打开一个线程来单独处理”的做法,而是采用事件驱动的模型,默认情况下,仅用单线程就可以负担相当高的并发量。
于是在这种情境下,我们说:
Node.js 更适合 IO密集型的任务处理
。但如果我们把上面的栗子更换一下,比如说咱们不开饭馆,开银行。每当客户到来,要求取出指定的款项,作为服务员,你需要根据客户的账户等级计算利率,计算利息,计算分红,等等……(随意想到的比方,可能不太恰当),而“取钱并交给客户”这个动作本身却并不复杂。
这时候,就不能指望像饭店那样,只靠一个服务员就能应付大量的客户,因为每个请求都需要独占服务员大量的时间(不可避免的
이 밤에서 우리는 웨이터가阻塞
CPU
에 해당하고, 주방의 업무가I/O
에 해당한다고 간단히 이해할 수 있습니다. 분명히 레스토랑에서 웨이터의 일은 복잡하지 않습니다. 대부분의 "음식을 기다리는 시간"은 "주방을 기다리는 시간"입니다. 이는 오늘날 대부분의 웹사이트의 상황과 유사합니다. 웹사이트는 일반적으로 너무 많은 복잡한 작업을 수행할 필요가 없지만 사진 및 비디오 읽기와 같은 데이터베이스 쿼리와 같은 I/O 처리를 기다리는 데 많은 시간을 소비해야 합니다. . 🎜 🎜그래서 Node.js는 기존 웹 서비스에서 "요청이 올 때마다 스레드를 열어 별도의 처리를 수행하는" 방식을 버리고 대신 기본적으로 단일 스레드만 높은 부담을 감당할 수 있는 모델을 채택했습니다. 동시성의. 🎜 🎜이러한 상황에서는Node.js가 IO 집약적인 작업 처리에 더 적합합니다
라고 말합니다. 🎜 🎜하지만 예를 들어 위의 밤을 바꾸면 식당이 아니라 은행을 열게 됩니다. 고객이 찾아와 일정 금액을 인출해 달라고 할 때마다 웨이터로서 고객의 계좌 레벨에 따라 이자율, 이자, 배당금 등을 계산해야 하는데... (임의의 비유는 아닐 수도 있음) 해당), "돈을 인출한다" 그리고 고객에게 넘겨준다" 이 동작 자체는 복잡하지 않습니다. 🎜 🎜현재로서는 각 요청마다 웨이터의 시간이 많이 필요하기 때문에 (필연차단
) 웨이터 한 명만으로는 레스토랑처럼 많은 수의 고객을 처리할 수 있다고 기대할 수 없습니다. 현재로서는 PHP와 같은 전통적인 모델이 더 적합해질 수 있습니다. 🎜 🎜위 내용을 통해 귀하의 혼란이 해소되기를 바랍니다🎜IO 집약적: 네트워크 전송, 데이터베이스 호출 등과 같이 IO가 많은 애플리케이션 대부분의 웹 애플리케이션은 이렇습니다
계산 집약적: 이름에서 알 수 있듯이 많은 CPU 계산이 필요한 애플리케이션 유형입니다. 클라우드 컴퓨팅과 같은 애플리케이션이 이 범주에 속합니다.
계산 집약적인 것은 무엇입니까? 예를 들어 SQLite 데이터베이스를 Linux 메모리 파일 시스템 /dev/shm에 배치하여 100만 개의 데이터에 대해 SELECT 쿼리 작업을 수행하면 B+ 트리 인덱스를 사용할 때 이 SELECT 쿼리가 실행됩니다. B+ 트리 인덱스에 대한 이진 검색은 인덱스를 사용하지 않는 경우 단순히 전체 테이블을 검색하는 것도 집약적인 계산이므로 관계형 데이터베이스와 같은 것들은 일반적으로 성능 보장 및 메모리 제어를 사용하여 구현됩니다. .
IO 집약적이란 무엇입니까? 예를 들어, SQLite 데이터베이스는 메모리에 없지만 일반 기계 디스크에서는 쓰기 작업(INSERT/UPDATE/DELETE)이 일반적인 IO 집약적 작업입니다. 왜냐하면 현재 CPU 속도가 아무리 빠르더라도 마찬가지이기 때문입니다. , SQLite 엔진은 더 빠르며 기계식 디스크의 쓰기 작업으로 인해 속도도 느려집니다. 따라서 동시성을 위해 SQLite는 나중에
WAL(write-ahead log)
쓰기를 도입했습니다. 특정 구성은 SQLite 쿼리를 실행하는 것입니다.WAL(write-ahead log)
预写式日志支持,具体配置就是执行一下SQLite查询:WAL机制的原理是: 修改并不直接写入到数据库文件中,而是写入到另外一个称为WAL的文件中(data.db3-wal). 如果事务失败,WAL中的记录会被忽略,撤销修改. 如果事务成功,它将在随后的某个时间(PRAGMA synchronous = NORMAL)被写回到数据库文件中,提交修改. 同步WAL文件和数据库文件的行为被称为checkpoint(检查点),它由SQLite自动执行, 默认是在WAL文件积累到1000页修改的时候(PRAGMA wal_autocheckpoint). 在适当的时候,也可以手动执行checkpoint,SQLite提供了相关的接口,执行 PRAGMA wal_checkpoint 之后,WAL文件会被清空. 在读的时候,SQLite将在WAL文件中搜索,找到最后一个写入点,记住它,并忽略在此之后的写入点(这保证了读写和读读可以并行执行). 随后,它确定所要读的数据所在页是否在WAL文件中,如果在,则读WAL文件中的数据,如果不在,则直接读数据库文件中的数据. 在写的时候,SQLite将之写入到WAL文件中即可,但是必须保证独占写入,因此写与写之间不能并行执行. WAL在实现的过程中,使用了共享内存技术(data.db3-shm),因此,所有的读写进程必须在同一个机器上,否则,无法保证数据一致性.
像WAL和checkpoint这种概念,在其他数据库比如MySQL中也存在,只不过MySQL会更复杂,能支持更大规模的并发写操作.像
WAL 메커니즘의 원칙은 수정 사항이 데이터베이스 파일에 직접 기록되지 않고 WAL(data.db3-wal)이라는 다른 파일에 기록된다는 것입니다. 트랜잭션이 실패하면 WAL의 레코드가 무시되고 수정이 취소됩니다. 트랜잭션이 성공하면 나중에 데이터베이스 파일에 다시 기록되고(PRAGMA 동기 = NORMAL) 수정을 커밋합니다. WAL 파일과 데이터베이스 파일을 동기화하는 동작을 체크포인트에 의해 자동으로 실행됩니다. SQLite는 WAL 파일이 1000페이지의 수정 사항을 누적하는 경우입니다(PRAGMA wal_autocheckpoint). 적절한 시점에 수동으로 체크포인트를 실행할 수도 있습니다. SQLite는 PRAGMA wal_checkpoint를 실행한 후 WAL 파일이 비어 있게 됩니다. 읽기를 수행하면 SQLite는 WAL 파일을 검색하여 마지막 쓰기 지점을 찾아 기억하고 이후 쓰기 지점을 무시합니다(이렇게 하면 읽기와 쓰기가 병렬로 수행될 수 있음). 이어서 데이터를 저장할 페이지를 결정합니다. WAL 파일에 있으면 WAL 파일에 있는 데이터를 읽습니다. 그렇지 않으면 데이터베이스 파일에 있는 데이터를 직접 읽습니다. 쓰기 시 SQLite는 이를 WAL 파일에 쓸 수 있습니다. 쓰기가 보장되어야 하므로 쓰기와 쓰기가 동시에 실행될 수 없습니다. WAL 구현 중에는 공유 메모리 기술(data.db3-shm)이 사용되므로 모든 읽기 및 쓰기 프로세스가 동일한 머신에서 이루어져야 합니다. 데이터 일관성은 보장할 수 없습니다.WAL+checkpoint
으아아아WAL+checkpoint
메서드와 같은 대규모 동시 쓰기 작업을 지원할 수 있다고 생각하면 됩니다. 비동기식 글쓰기.🎜 🎜Node의 JS 인터프리터는 Chromium의 V8을 기반으로 하며 V8에는 JIT JIT 컴파일 메커니즘이 있으므로 Node의 집약적 컴퓨팅 성능은 PHP보다 낮습니다. PHP 관계자가 현재 PHP의 JIT 테스트를 개발하고 있지만 성능은 여전히 좋지 않습니다. V8. 그러나 Node가 좋은 컴퓨팅 성능을 갖고 있다고 해도 Node에서 대규모 집약적 계산을 수행하는 것을 권장하는 사람은 거의 없습니다. 왜냐하면 집약적인 컴퓨팅 소비로 인해 필연적으로 Node 서비스가 차단될 것이기 때문입니다. 이는 Node가 주장하는 비차단 개념에 어긋납니다.🎜Node는 JS의 이벤트 중심 특성을 사용하여 논블로킹을 달성하지만 콜백 기반 이벤트 프로그래밍 방법은 코드 유지 관리에 도움이 되지 않습니다. 또한 Node와 같은 서비스는 Java와 같은 단일 프로세스, 멀티스레딩 및 멀티 코어를 사용할 수 없습니다. Tomcat과 같은 서비스, V8은 그렇지 않습니다. 멀티스레딩용으로 설계되지 않았기 때문에 Node 관계자는 멀티코어를 활용하기 위해 클러스터 다중 프로세스 모듈만 구축할 수 있습니다.
PHP는 상대적으로 평범하고 계산 속도가 JIT 언어만큼 빠르지는 않습니다. 그러나 JIT가 아닌 일반 스크립트 언어 중에서는 PHP가 느리지 않습니다. 예를 들어 PHP5는 이미 Python보다 빠르며 PHP7은 훨씬 빠릅니다. php-src 같은 Python보다 /Zend/bench.php 테스트에서 PHP 7.1의 시간 소모는 5.4의 1/4에 불과합니다.
또한 PHP의 PHP-FPM 및 Apache MOD_PHP와 같은 다중 프로세스 FastCGI 실행 방법은 다중 코어를 쉽게 활용할 수 있습니다. 또한 opcache를 활성화하여 PHP 스크립트의 opcode를 공유 메모리에 캐시할 수도 있습니다. function.php의 많은 기능은 opcache가 메모리에 스크립트를 캐시한 후에 PHP가 요청될 때마다 스크립트를 다시 구문 분석할 필요가 없으며 opcode를 직접 실행할 수 있으며 특히 복잡한 경우 성능 향상이 매우 분명합니다. PHP 애플리케이션.