nodejs 비동기식 구조안에서 루프형태의 mysql update 처리

조회수 1639회

php개발만 하다 nodejs 에 입문한 초보입니다.

우선 구현하고자 하는 구조를 말씀드리면

  1. mysql select로 limit 10~50개 정도의 레코드를 추출
  2. 루프를 돌려 idx와 url을 추출
  3. request모듈을 사용하여 자사 다른서버에 접근 정보를 가져옴
  4. idx 기준으로 업데이트

위와 같은 구조를 비동기식으로 만들어보고 싶어

async.waterfall([
    function(cb) {
        connection.query("SELECT idx, url FROM table LIMIT 5", function(err, rows, fields) {
            if(err) { throw err; }
            if(rows.length > 0) {
                cb(null, rows);
            } else {
                cb(err);
            }
        });
    },
    function(data, cb) {
        async.parallel([
            function(pcb) {
                for(var i=0;i<data.length;i++) {
                    var idx = data[i].idx;
                    var url = data[i].link;
                    request(url, function(error, response, html){  
                        // { 중간생략 }
            var upQuery = "UPDATE table SET text = 'a' WHERE idx = '"+idx+"' ";
            connection.query(upQuery);
                    });
                    pcb(null, "ok");
                }
            }
        ], function(err, result) {
            connection.end();
            cb(err, result);
        });
    }
], function(err, result) {
    if( err ) {
        console.log( err );
    }
});

문제는 for문 안에서는 동기식으로 업데이트가 되는거 같아 connection.end()로 mysql connection이 종료되버린후에 update가 진행되는것 같습니다.

select에서 가져온 레코드수를 받아 처리는 동기식으로 하되 종료되는 시점을 판단하여 connection.end를 처리하고 싶습니다.

도움 부탁드립니다. (_ _)

  • (•́ ✖ •̀)
    알 수 없는 사용자
  • 제가 볼때는 트랜잭션 문제 같아 보입니다. update 처리를 반복적으로하다 end 호출시 commit 되는 것 같습니다. 정영훈 2018.5.4 23:34
  • 5개의 레코드를 업데이트해도 동기식으로 처리되다 보니 connection.end()가 먼저 처리되는거 같습니다. 알 수 없는 사용자 2018.5.4 23:38
  • 동기와 비동기를 혼동하는 것 같은데요? 비동기다보니 순서를 알 수 없는겁니다. 동기면 순서대로 실행합니다. 정영훈 2018.5.4 23:45
  • 제가 혼동했나봅니다. 그렇다면 parallel로 처리하는것 자체가 잘못된것일까요? 사실 for문 안에서 i와 data.length를 비교해서 connection.end 처리를 하긴했지만 그게 답은 아닌거 같아 계속 찾아보고 있습니다. 알 수 없는 사용자 2018.5.4 23:50
  • 데이터 update 하는 작업을 왜 비동기적으로 하는 건가요? 비동기는 다루기가 힘듭니다. 정영훈 2018.5.4 23:57
  • 데이터 업데이트전의 request를 빠르게 하고 싶었습니다. php로 만들어놓은 기존 작업들을 개선해보고자 nodejs를 시작해보고 싶었습니다. 알 수 없는 사용자 2018.5.5 00:00
  • 성능은 동기가 더 빠릅니다. nodejs 가 인기를 얻는 이유는 성능이 아니라 가용성(c10k문제)입니다. nodejs가 비동기로 많은 접속을 커버할 수 있는 것이지 처리 성능은 느립니다. 프로그램 설계를 request 한번 update 한번 이렇게 하지 말고 request 를 모두 끝내 관련 데이터를 저장하고 그 관련데이터로 update 만 처리하는 식이 훨씬 빠릅니다. 정영훈 2018.5.5 00:08
  • 그렇다면 request 결과를 배열로 담고 waterfall 다음 함수에서 한번에 UPDATE 치더라고 connection.end는 같은 현상이 생기지 않을까요? 알 수 없는 사용자 2018.5.5 00:18
  • 제 생각에 하려는 작업은 비동기로 해서 얻는 잇점이 거의 없는 것 같습니다. limit 수가 많으면 많을수록 처리시간은 길어질겁니다. 그냥 동기적으로 처리하는게 가장 빠를것으로 보입니다. 정영훈 2018.5.5 00:28
  • 한가지 nodejs 는 멀티쓰레드가 지원되는 구조가 아닙니다. python 과 마찬가지로 GIL 같은 형식의 lock을 겁니다. 쉽게 예를들어 코어가 4개달린 cpu에서 nodejs 로 서비스를 하면 다수의 사용자가 접속을 해도 코어 1개만 사용합니다. 정영훈 2018.5.5 00:35
  • 조언 감사합니다. 이 작업은 백단에서 스케쥴러로 이미 만들어진 십만단위의 레코드를 업뎃하려고 하려고 시도중인거라 말씀하신대로 limit 수가 서버에 부하를 일으킬 정도는 아닙니다.. 단지 50개 미만의 레코드를 php과는 다르게 비동기로 처리하는 과정에 대해 알고 싶었습니다. 알 수 없는 사용자 2018.5.5 00:39
  • 아 단지 학습의 목적이었다면 테스트를 해보셔야 할 것 같습니다. 저는 nodejs 에 대해 기능적으로 많이 알지는 못합니다. 정영훈 2018.5.5 00:46
  • 학습은 아니고.. 말씀드렸다시피 crontab을 통한 적은 limit로 데이터 교체가 목적입니다..-_- 알 수 없는 사용자 2018.5.5 01:02
  • 단지 php로 쉽게 할수 있고 이미 하고 있지만 nodejs라는 도구로 비동기형태로 처리하고 싶은거죠.. 알 수 없는 사용자 2018.5.5 01:03

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)