1. 程式人生 > >用戶增長量統計項目實現過程踩坑總結

用戶增長量統計項目實現過程踩坑總結

多進程、多線程、crontab

最近一段時間在做一個用戶訪問量統計的小項目,主要實現根據打包好的rdb文件進行解析、統計,然後存到pika,然後取到用戶key並統計訪問量的增長並將數據推到 grafana 進行展示。在代碼實現及部署過程中遇到了一些問題,總結出來,以備後續參考。歡迎批評指正,共同學習!


一、在函數中使用多進程正常執行,在類中出現報錯

技術分享解決方式如下:

1、導入模塊:

import types
import copy_reg

2、增加函數

def _pickle_method(m):
    if m.im_self is None:
        return getattr, (m.im_class, m.im_func.func_name)
    else:
    return getattr, (m.im_self, m.im_func.func_name)
copy_reg.pickle(types.MethodType, _pickle_method)

3、在類中增加如下方法

def __init__(self):
    self.__result = []
def result_collector(self, result):
    self.__result.append(result)


二、多進程的重復使用

在實現Redis key 的讀寫采集過程中,在數據采集中用到多進程提高效率,在得到結果往 pika 中存儲 key 時,為提高效率,想采用多進程,但測試發現多進程嵌套使用多進程,會出現如下問題 :

Queue objects should only be shared between processes through inheritance

後來考慮到往pika中存數據屬於io密集型的操作,因此,采用了多線程,解決了這一問題。這裏涉及到多線程如何使主進程等待多個子線程執行完畢,解決方式如下:

t_objs = []
for i in range(100):
    t = threading.Thread(target=self.batch_send_pika,args=(set_key, redis_port, all_batch_message[i]))
    t.start()
    t_objs.append(t)
for t in t_objs:
    t.join() #等待線程的執行結果


三、多進程之間多個Queue實現數據共享

在實現用戶讀寫訪問量統計的過程中,由於每條產品線涉及多個端口,每條產品線又有多條規則,為了提高效率,因此對同一條產品線的不同端口采用多進程來實現,要統計同一產品線的用戶增長量,就需要對同一規則不同端口之間的數據進行匯總求和,這裏就涉及到每條規則啟動一個Queue,對不同的端口采集到的數據存到Queue中,然後進行統計。因為要啟動多個Queue,還要保證數據和的準確性,這裏遇到了一些坑。嘗試通過循環拼接字符串啟動Queue、嘗試過將Queue啟動後加入列表作為參數進行傳遞使用,但是都沒有成功,後來通過查資料學習,解決了這一問題。解決方式如下:

from multiprocessing import Queue,Manager
    
q_list = []
for i in range(len(rule_list)):
    q_name = "q" + str(i)
    manager = Manager()
    q_name = manager.Queue()
    q_list.append(q_name)

然後將q_list作為參數進行傳遞即可


四、crontab報錯

在使用計劃任務時未修改成功,遇到如下報錯

crontab: installing new crontab

crontab: error while writing new crontab to /var/spool/cron/tmp.XXXXa2LhEO

crontab: edits left in /tmp/crontab.rEpgqL

解決方式如下:

查看磁盤空間和inode節點是否用盡

技術分享

技術分享

這裏發現/var 目錄磁盤空間已經用盡將/var 下無用的文件進行刪除,解決了這一問題

技術分享


本文出自 “10917734” 博客,請務必保留此出處http://10927734.blog.51cto.com/10917734/1957082

用戶增長量統計項目實現過程踩坑總結