記一次大批量數據的多進程同步
背景:因為公司的用戶標識不完整,所以需要從集團同步一次用戶標記數據,用戶數據來源是微信,數量級為一百五十萬,集團用戶數量級為六百萬
方案確定下來是集團開了一個查詢接口,訪問沒有頻率並發限制,數量級在那呢,我們遍歷公司的用戶,去查詢這些用戶的標識來更新
項目使用了laravel,就寫了一個命令行腳本,開15個進程去跑
由於時間關系使用了PHP的pcntl_fork實現多進程
核心代碼如下:
主要流程是:
首先主進程分配userid給各個子進程,這里使用了redis隊列來存儲,然后fork子進程,在子進程中pop隊列獲取分配到的userid范圍,再查庫組裝信息請求集團API,根據返回值標示用戶。
因為Laravel封裝的redis和DB使用了單例,所有多個進程多錢redis和DB時均有報錯:
redis:Error while reading line from the server
mysql:Packets out of order. Expected 1 received 19
嗯,都是多進程讀取單例的同一個連接導致的,解決方案:
redis:使用原生PHP的redis連接:
$redis = new \Redis(); $re1 = $redis->connect(env('REDIS_HOST'),env('REDIS_PORT')); $re2 = $redis->auth(env('REDIS_PASSWORD'));
mysql:使用laravel的purge 和reconnetc重新連接
DB::purge('mysql'); DB::reconnect('mysql');
多線程大批量數據問題解決^_^