天天看點

【OpenStack】OpenStack中的循環任務--以Nova為例

聲明:

本部落格歡迎轉發,但請保留原作者資訊!

新浪微網誌:@孔令賢HW;

部落格位址:http://blog.csdn.net/lynn_kong

内容系本人學習、研究和總結,如有雷同,實屬榮幸!

版本:Grizzly

說到循環任務,可能很多人首先想到的是python中的threading或者multiprocessing子產品,使用起來相當的便利,但OpenStack有些例外。OpenStack中使用了大量的所謂的“綠色線程”(或者叫協程,與線程差別),而eventlet庫基本包含了普通線程的所有操作,同時避免了線程切換帶來的開銷,在性能方面優于線程。關于eventlet,我并不是很懂,可以閱讀其官方文檔:http://eventlet.net/doc/index.html

為了實作定時循環任務,OpenStack自身又封裝了eventlet實作了兩種循環任務:

1. 定時間隔,即任務的兩次執行會間隔特定的時間;

2. 動态間隔,即任務的第二次執行由第一次執行的傳回值确定,這裡要求任務要傳回一個時間間隔。

以Nova為例,每個相關的Nova程序都會根據配置項來配置相關的循環任務。配置項主要有:

periodic_enable:表示是否允許執行循環任務(True/False)。
periodic_fuzzy_delay:一個時間值(機關是秒),每個程序啟動時,會從這個時間值内随機選擇一個時間作為循環任務的初始延遲。
periodic_interval_max:循環任務的最大執行間隔。動态間隔類型的任務使用,任務兩次執行的間隔由該值和任務傳回時間值的最小值确定。
           

1. 循環任務periodic_tasks

關于periodic_tasks,在我早期的一篇部落格中有講到(http://blog.csdn.net/lynn_kong/article/details/8244364),這裡主要關注任務執行的間隔。periodic_task是動态間隔類型,一個periodic_tasks的執行,包含了許多子任務,每一個子任務又有各自不同的設定:

external_process_ok:(True/False)表示可以在單獨程序中執行的任務。如果配置項run_external_periodic_tasks為False,則該屬性為True的任務不在循環任務中執行(會由獨立的程序執行)。
enabled:子任務是否可以執行。
spacing:子任務執行的大概的時間間隔,這個值并不是特别的精确。如果小于0,則不執行。沒有設定時間間隔的子任務會在periodic_tasks的每次執行時運作。
run_immediately:(True/False)是否立即執行。
           

兩次periodic_task的執行間隔,是idle time和periodic_interval_max的最小值決定。這裡的periodic_interval_max是配置項,而idle time就跟每一個子任務的執行有關。具體來說:

1. idle time有一個初始值60s;

2. 如果所有的子任務都沒有設定spacing的值,則兩次periodic_task的執行間隔就是60s(從第一次執行完畢到第二次執行開始的時間間隔)

3. 如果一個子任務設定了spacing的值,但還沒到執行時間,則将idle time設定為距離該子任務下次執行的等待時間;

4. 如果一個子任務成功執行,且它的spacing小于目前的idle time,則将idle time設定為spacing的值;

子任務循環結束後,periodic_task傳回idle time,就是periodic_task要睡眠的時間。

上面是以periodic_task的視角來說明兩次periodic_task的執行間隔如何确定。下面以某一個子任務的視角,來說明periodic_task執行時,子任務的處理政策:

1. 如果子任務沒有配置spacing,執行(子任務兩次執行的最小間隔是60s);

2. 如果子任務配置了spacing,但還沒到執行時間(距離上次執行的時間間隔小于spacing的值),将idle time設定為等待時間(如果等待時間小于目前的idle time的值);

3. 如果子任務配置了spacing,并且到了執行時間,執行。将idle time設定為spacing的值(如果spacing的值小于idletime);

2. 子任務

Nova中目前有14個子任務,分别為:

1) _check_instance_build_time

配置instance_build_timeout時執行。将BUILDING持續時間超過instance_build_timeout的虛拟機狀态置為ERROR。這裡不區分虛拟機是否在本節點。

2) _heal_instance_info_cache

找到本機的一個虛拟機,從Quantum擷取并更新虛拟機網絡資訊,(instance_info_caches表)

3) _poll_rebooting_instances(libvert沒有實作)

調用driver的poll_rebooting_instances方法

4) _poll_rescued_instances

配置rescue_timeout大于0時執行。對本節點中狀态為rescued且持續時間大于rescue_timeout的虛拟機,執行unrescue操作

5) _poll_unconfirmed_resizes

配置resize_confirm_window 大于0時執行。resize虛拟機後(虛拟機在本機是resized狀态),過了resize_confirm_window配置的時間,從migrations表中找出記錄,執行confirm_resize操作

6) _instance_usage_audit

虛拟機審計。如果配置項instance_usage_audit為True,且task_log表中不存在最近一個周期(instance_usage_audit_period,預設是month)的審計記錄時,執行。從資料庫中擷取在一個周期記憶體在(包括在周期内删除和新建立)的虛拟機資訊,并調用notifier.notify(),同時增加task_log表的審計記錄

7) _poll_bandwidth_usage(libvert沒有實作)

每隔bandwidth_poll_interval運作一次,運作時調用driver的get_all_bw_counters方法,更新bw_usage_cache表

8) _poll_volume_usage(G版新增)

如果配置項volume_usage_poll_interval不等于0執行。同樣使用TaskLog表的資訊,如果目前時刻與上一周期開始的時間間隔大于volume_usage_poll_interval執行。首先擷取本機上所有虛拟機挂載的卷,作為driver的get_all_volume_usage方法的入參(目前隻有libvert實作該方法),擷取卷的使用資訊,更新volume_usage_cache表。

9) _report_driver_status(提供給nova-scheduler使用)

每隔host_state_interval運作一次,運作時調用driver的get_host_stats方法,更新manager對象的last_capabilities屬性,這個屬性會定時上報給nova-scheduler作為排程依據。内容包括:vcpu,disk,memory,hypervisor等資訊。

10) _sync_power_states,虛拟機狀态重新整理,spacing=600

擷取db中本機上的虛拟機,(會調用driver的get_num_instances方法擷取虛拟機個數),根據db中的虛拟機做循環:

a) 忽略有task_state(正在處理)的虛拟機

b) 調用driver的get_info方法擷取節點虛拟機資訊,若找不到,power_state=NOSTATE

c) 若db中的power_state與driver傳回的power_state不一緻,以driver為準,更新db

d) 若db中的vm_state=BUILDING|RESCUED|RESIZED|SUSPENDED|PAUSED|ERROR,忽略

e) 若db中的vm_state==ACTIVE,而power_state是[SHUTDOWN, CRASHED, SUSPENDED],調用nova-api的stop接口停止虛拟機;如果power_state是[PAUSED|NOSTATE],忽略

f) 若db中的vm_state==STOPPED,而power_state不是[NOSTATE, SHUTDOWN, CRASHED],調用nova-api的stop接口停止虛拟機

11) _reclaim_queued_deletes

删除過期的soft_delete的虛拟機(前提:reclaim_instance_interval大于0)。

12) update_available_resource,主機資源重新整理

保證主機記錄的資源使用(ResourceTracker)與底層的hypervisor的使用情況一緻。

13) _cleanup_running_deleted_instances,spacing=running_deleted_instance_poll_interval,預設是1800

找到本機中在DB中是deleted狀态,但在虛拟化層仍然存在的虛拟機(調用driver的list_instances方法),若删除時間大于running_deleted_instance_timeout,按照running_deleted_instance_action配置的方式處理(noop, log, reap)

14) _run_image_cache_manager_pass,spacing=image_cache_manager_interval,預設是2400

要求driver的capabilities["has_imagecache"]為True,且配置image_cache_manager_interval時執行。管理本地鏡像檔案緩存。就是把長時間不使用的鏡像檔案緩存删除掉。這裡需要注意的是,使用共享存儲時的時間配置。因為一個compute node不需要的鏡像緩存,可能會被其他compute node使用。

繼續閱讀