Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC

Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC

Linux dia manana fitaovana be dia be amin'ny debugging ny kernel sy ny fampiharana. Ny ankamaroan'izy ireo dia misy fiantraikany ratsy amin'ny fampiharana fampiharana ary tsy azo ampiasaina amin'ny famokarana.

Roa taona lasa izay dia nisy fitaovana iray hafa novolavolaina - eBPF. Izy io dia ahafahana manara-maso ny kernel sy ny rindranasan'ny mpampiasa amin'ny vidiny ambany ary tsy mila manangana programa sy mampiditra ireo maody an'ny antoko fahatelo ao anaty kernel.

Efa misy fitaovana fampiharana maro izay mampiasa eBPF, ary ato amin'ity lahatsoratra ity dia hojerentsika ny fomba hanoratana ny mombamomba anao manokana mifototra amin'ny tranomboky. PythonBCC. Ny lahatsoratra dia mifototra amin'ny zava-nitranga tena izy. Andeha isika handamina ny olana mba hampisehoana ny fomba azo ampiasaina amin'ny toe-javatra manokana.

Miadana i Ceph

Nampiana mpampiantrano vaovao ao amin'ny cluster Ceph. Taorian'ny nifindrany ny angon-drakitra sasany ho azy, dia tsikaritray fa ambany lavitra noho ny amin'ny lohamilina hafa ny hafainganam-pandehan'ny fanodinana ny fangatahana fanoratana ataon'izy io.

Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC
Tsy toy ny sehatra hafa, ity mpampiantrano ity dia nampiasa bcache sy ny kernel linux 4.15 vaovao. Ity no fotoana voalohany nampiasana an'ity tefy ity teto. Ary tamin'izany fotoana izany dia nazava fa ny fototry ny olana dia mety ho na inona na inona.

Fanadihadiana ny Mpampiasa

Andeha isika hanomboka amin'ny fijerena izay mitranga ao anatin'ny dingana ceph-osd. Ho an'ity dia hampiasaintsika tonga lafatra ΠΈ flamescope (bebe kokoa momba izay azonao vakiana eto):

Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC
Ny sary dia milaza amintsika fa ny asa fdatasync() nandany fotoana be nandefa fangatahana ho an'ny asa generic_make_request(). Midika izany fa mety ho any ivelan'ny daemon osd mihitsy no mahatonga ny olana. Ity dia mety ho kernel na disks. Ny vokatra iostat dia nampiseho fahatarana ambony amin'ny fanodinana fangatahana amin'ny kapila bcache.

Rehefa nanamarina ny mpampiantrano izahay dia nahita fa ny daemon systemd-udevd dia mandany fotoana betsaka amin'ny CPU - eo amin'ny 20% amin'ny cores maromaro. Fihetsika hafahafa izany, ka mila fantarinao ny antony. Satria miara-miasa amin'ny uevents ny Systemd-udevd, dia nanapa-kevitra ny hijery azy ireo izahay udevadm monitor. Hita fa be dia be ny hetsika fanovana natao ho an'ny fitaovana sakana tsirairay ao amin'ny rafitra. Hafahafa ihany izany, ka tsy maintsy hojerentsika izay mahatonga ireo hetsika rehetra ireo.

Mampiasa ny BCC Toolkit

Araka ny efa hitantsika, ny kernel (sy ny daemon ceph ao amin'ny rafitra antso) dia mandany fotoana be generic_make_request(). Andeha hojerentsika ny hafainganam-pandehan'ity asa ity. IN mpametraka Efa misy fitaovana mahafinaritra - Funclatency. Hanara-maso ny daemon amin'ny PID miaraka amin'ny elanelana 1 segondra eo anelanelan'ny vokatra isika ary mamoaka ny vokatra ao anatin'ny milisegondra.

Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC
Ity fampiasa ity matetika dia miasa haingana. Ny hany ataony dia ny mandefa ny fangatahana amin'ny filaharana mpamily fitaovana.

Bcache dia fitaovana sarotra izay misy kapila telo tokoa:

  • fitaovana fanohanana (kapila cached), amin'ity tranga ity dia HDD miadana;
  • fitaovana caching (kapila caching), ity dia fizarana iray amin'ny fitaovana NVMe;
  • ny fitaovana virtoaly bcache izay iasan'ny fampiharana.

Fantatray fa miadana ny fandefasana fangatahana, fa ho an'iza amin'ireo fitaovana ireo? Hiatrika izany isika aoriana kely.

Fantatray izao fa mety hiteraka olana ny uevents. Tsy mora ny fitadiavana izay tena mahatonga ny taranany. Andeha hatao hoe karazana logiciel atomboka tsindraindray ity. Andeha hojerentsika hoe karazana rindrambaiko mandeha amin'ny rafitra mampiasa script execsnoop avy amin'ny mitovy Vidin'ny BCC. Alefaso ary alefa amin'ny rakitra ny vokatra.

Ohatra toy izao:

/usr/share/bcc/tools/execsnoop  | tee ./execdump

Tsy hampiseho ny vokatra feno an'ny execsnoop eto izahay, fa ny andalana iray mahaliana anay dia toy izao:

sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:/]' '{print $2}' | sed 's/^ ([0-9]*) C.*/1/'

Ny tsanganana fahatelo dia ny PPID (PID ray aman-dreny) amin'ny dingana. Ny dingana miaraka amin'ny PID 5802 dia nanjary iray amin'ireo kofehy amin'ny rafitra fanaraha-maso. Rehefa nanamarina ny fanamafisana ny rafitra fanaraha-maso dia hita ny masontsivana diso. Ny hafanan'ny adaptatera HBA dia nalaina isaky ny 30 segondra, izay matetika kokoa noho ny ilaina. Taorian'ny nanovany ny elanelam-potoana fanamarinana ho lava kokoa, dia hitanay fa tsy nisongadina intsony ny faharetan'ny fanodinana fangatahana amin'ity mpampiantrano ity raha oharina amin'ireo mpampiantrano hafa.

Saingy mbola tsy mazava ny antony nahatonga ilay fitaovana bcache miadana. Nanomana sehatra fitsapana miaraka amin'ny fandrindrana mitovy izahay ary nanandrana namerina ny olana tamin'ny alΓ lan'ny fampandehanana fio amin'ny bcache, mandeha tsindraindray ny trigger udevadm mba hamoronana uevents.

Manoratra Fitaovana Miorina amin'ny BCC

Andao hiezaka hanoratra fitaovana tsotra hanohizana sy hanehoana ireo antso miadana indrindra generic_make_request(). Mahaliana ihany koa ny anaran'ny fiara izay niantsoana an'io fiasa io.

Tsotra ny drafitra:

  • hisoratra anarana kprobe amin'ny generic_make_request():
    • Tehirizo ao anaty fitadidiana ny anaran'ny kapila, azo idirana amin'ny alΓ lan'ny tohan-kevitra fiasa;
    • Tehirizinay ny mari-pamantarana.

  • hisoratra anarana kretprobe ho fiverenana avy generic_make_request():
    • Mahazo ny mari-pamantarana amin'izao fotoana izao izahay;
    • Mitady ny mari-pamantarana voatahiry izahay ary mampitaha izany amin'ny ankehitriny;
    • Raha lehibe noho ilay voatondro ny vokatra, dia hitantsika ny anaran'ny kapila voatahiry ary asehoy eo amin'ny terminal.

Kprobes ΠΈ kretprobes mampiasa mekanika breakpoint hanova ny kaody fampiasa amin'ny lalitra. Afaka mamaky ianao tahirin-kevitra ΠΈ tsara lahatsoratra momba ity lohahevitra ity. Raha mijery ny code of utility isan-karazany ao mpametraka, dia ho hitanao fa manana rafitra mitovy izy ireo. Ka ato amin'ity lahatsoratra ity isika dia hitsambikina ireo tohan-kevitry ny script ary hifindra amin'ny programa BPF mihitsy.

Ny lahatsoratra eBPF ao anatin'ny script python dia toy izao:

bpf_text = β€œβ€β€ # Here will be the bpf program code β€œβ€β€

Mba hifanakalozana angon-drakitra eo amin'ny fiasa dia mampiasa programa eBPF tabilao hash. Hanao toy izany koa isika. Hampiasa ny dingana PID ho fanalahidy izahay, ary hamaritra ny rafitra ho sandany:

struct data_t {
	u64 pid;
	u64 ts;
	char comm[TASK_COMM_LEN];
	u64 lat;
	char disk[DISK_NAME_LEN];
};

BPF_HASH(p, u64, struct data_t);
BPF_PERF_OUTPUT(events);

Eto isika dia manoratra tabilao hash antsoina hoe p, miaraka amin'ny karazana fanalahidy u64 ary sanda iray karazana struct data_t. Ny tabilao dia ho hita ao anatin'ny tontolon'ny programa BPF. Ny macro BPF_PERF_OUTPUT dia manoratra tabilao hafa antsoina zava-mitranga, izay ampiasaina amin'ny fandefasana angona ao amin'ny habaka mpampiasa.

Rehefa mandrefy ny fahatarana eo anelanelan'ny fiantsoana asa iray sy ny fiverenana avy aminy, na eo anelanelan'ny fiantsoana amin'ny asa samihafa, dia mila raisinao fa ny angon-drakitra voaray dia tsy maintsy mifanaraka amin'ny contexte iray ihany. Raha lazaina amin'ny teny hafa, mila mitadidy momba ny mety ho fanombohana parallèle ny asa. Manana fahafahana mandrefy ny elanelam-potoana eo anelanelan'ny fiantsoana asa iray ao anatin'ny tontolon'ny dingana iray sy ny fiverenana avy amin'io fiasa io ao anatin'ny tontolon'ny dingana iray hafa isika, saingy azo inoana fa tsy misy ilàna azy izany. Ohatra tsara eto fampiasana biolatency, izay ametrahana ny fanalahidin'ny latabatra hash amin'ny tondro fangatahana struct, izay maneho ny fangatahana kapila iray.

Manaraka, mila manoratra ny kaody izay handeha isika rehefa antsoina hoe ny asa eo ambany fianarana:

void start(struct pt_regs *ctx, struct bio *bio) {
	u64 pid = bpf_get_current_pid_tgid();
	struct data_t data = {};
	u64 ts = bpf_ktime_get_ns();
	data.pid = pid;
	data.ts = ts;
	bpf_probe_read_str(&data.disk, sizeof(data.disk), (void*)bio->bi_disk->disk_name);
	p.update(&pid, &data);
}

Eto ny hevitra voalohany amin'ny asa antsoina dia hosoloina ho toy ny hevitra faharoa generic_make_request(). Aorian'izany dia mahazo ny PID amin'ny dingana isika amin'ny toe-javatra iasantsika, ary ny mari-potoana ankehitriny amin'ny nanoseconds. Soratanay ao anaty sora-baventy vao voafantina daholo izany struct data_t data. Mahazo ny anaran'ny kapila izahay avy amin'ny rafitra mombamomba, izay mandalo rehefa miantso generic_make_request(), ary tehirizo amin'ny rafitra iray ihany tahirin-kevitra. Ny dingana farany dia ny manampy ny fidirana amin'ny latabatra hash izay voalaza teo aloha.

Ity asa manaraka ity dia hantsoina rehefa miverina avy generic_make_request():

void stop(struct pt_regs *ctx) {
    u64 pid = bpf_get_current_pid_tgid();
    u64 ts = bpf_ktime_get_ns();
    struct data_t* data = p.lookup(&pid);
    if (data != 0 && data->ts > 0) {
        bpf_get_current_comm(&data->comm, sizeof(data->comm));
        data->lat = (ts - data->ts)/1000;
        if (data->lat > MIN_US) {
            FACTOR
            data->pid >>= 32;
            events.perf_submit(ctx, data, sizeof(struct data_t));
        }
        p.delete(&pid);
    }
}

Ity fiasa ity dia mitovy amin'ny teo aloha: hitantsika ny PID amin'ny dingana sy ny fe-potoana, fa tsy manome fahatsiarovana ho an'ny rafitra data vaovao. Fa kosa, mikaroka ny latabatra hash isika amin'ny rafitra efa misy amin'ny fampiasana ny lakile == PID ankehitriny. Raha hita ny rafitra, dia hitantsika ny anaran'ny dingana mihazakazaka ary ampio izany.

Ny fiovan'ny binary ampiasaintsika eto dia ilaina hahazoana ny kofehy GID. ireo. PID ny dingana lehibe izay nanomboka ny kofehy amin'ny toe-javatra iasanay. Ny asa antsoinay bpf_get_current_pid_tgid() mamerina ny GID an'ny kofehy sy ny PID ao anaty sanda 64-bit tokana.

Rehefa mivoaka amin'ny terminal isika dia tsy liana amin'ny kofehy amin'izao fotoana izao, fa liana amin'ny dingana lehibe. Aorian'ny fampitahana ny fahatarana aterak'izany amin'ny tokonam-baravarana iray dia mandalo ny rafitray izahay tahirin-kevitra mankany amin'ny habaka mpampiasa amin'ny alΓ lan'ny latabatra zava-mitranga, avy eo dia mamafa ny fidirana amin'ny p.

Ao amin'ny script python izay hampiditra an'io kaody io dia mila manolo ny MIN_US sy FACTOR miaraka amin'ny tokonam-baravaran'ny fanemorana sy ny fe-potoana isika, izay handalo ny tohan-kevitra:

bpf_text = bpf_text.replace('MIN_US',str(min_usec))
if args.milliseconds:
	bpf_text = bpf_text.replace('FACTOR','data->lat /= 1000;')
	label = "msec"
else:
	bpf_text = bpf_text.replace('FACTOR','')
	label = "usec"

Ankehitriny dia mila manomana ny programa BPF amin'ny alΓ lan'ny BPF macro ary misoratra anarana santionany:

b = BPF(text=bpf_text)
b.attach_kprobe(event="generic_make_request",fn_name="start")
b.attach_kretprobe(event="generic_make_request",fn_name="stop")

Tsy maintsy hamaritra ihany koa isika struct data_t ao amin'ny scripty, raha tsy izany dia tsy ho afaka hamaky na inona na inona izahay:

TASK_COMM_LEN = 16	# linux/sched.h
DISK_NAME_LEN = 32	# linux/genhd.h
class Data(ct.Structure):
	_fields_ = [("pid", ct.c_ulonglong),
            	("ts", ct.c_ulonglong),
            	("comm", ct.c_char * TASK_COMM_LEN),
            	("lat", ct.c_ulonglong),
            	("disk",ct.c_char * DISK_NAME_LEN)]

Ny dingana farany dia ny famoahana data amin'ny terminal:

def print_event(cpu, data, size):
    global start
    event = ct.cast(data, ct.POINTER(Data)).contents
    if start == 0:
        start = event.ts
    time_s = (float(event.ts - start)) / 1000000000
    print("%-18.9f %-16s %-6d   %-1s %s   %s" % (time_s, event.comm, event.pid, event.lat, label, event.disk))

b["events"].open_perf_buffer(print_event)
# format output
start = 0
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()

Ny script mihitsy dia hita ao amin'ny GItHub. Andeha isika hanandrana azy io amin'ny sehatra fitsapana misy fio mihazakazaka, manoratra amin'ny bcache, ary miantso ny udevadm monitor:

Avy amin'ny High Ceph Latency mankany Kernel Patch miaraka amin'ny eBPF/BCC
Farany! Hitantsika izao fa ny toa ny fitaovana bcache miato dia antso miato generic_make_request() ho an'ny kapila misy cache.

Hiverina any amin'ny Kernel

Inona marina no miadana mandritra ny fandefasana fangatahana? Hitantsika fa mitranga ny fahatarana na dia alohan'ny hanombohan'ny kaonty fangatahana aza, i.e. tsy mbola nanomboka ny kaonty fangatahana manokana momba ny famoahana antontan'isa momba izany (/proc/diskstats na iostat). Azo hamarinina mora foana izany amin'ny alΓ lan'ny fampandehanana iostat rehefa mamerina ny olana, na BCC script biolatency, izay mifototra amin'ny fanombohana sy fiafaran'ny kaonty fangatahana. Tsy misy amin'ireo fitaovana ireo no hampiseho olana amin'ny fangatahana amin'ny kapila cache.

Raha jerena ny asa generic_make_request(), dia ho hitantsika fa alohan'ny hanombohan'ny fitakiana kaonty dia misy asa roa hafa antsoina. Voalohany - generic_make_request_checks(), manao fisavana ny maha-ara-dalΓ na ny fangatahana momba ny firafitry ny kapila. Faharoa - blk_queue_enter(), izay manana fanamby mahaliana miandry_event_interruptible():

ret = wait_event_interruptible(q->mq_freeze_wq,
	(atomic_read(&q->mq_freeze_depth) == 0 &&
	(preempt || !blk_queue_preempt_only(q))) ||
	blk_queue_dying(q));

Ao anatin'izany, ny kernel dia miandry ny filaharana tsy hivaingana. Andeha horefesina ny fahatarana blk_queue_enter():

~# /usr/share/bcc/tools/funclatency  blk_queue_enter -i 1 -m               	 
Tracing 1 functions for "blk_queue_enter"... Hit Ctrl-C to end.

 	msecs           	: count 	distribution
     	0 -> 1      	: 341  	|****************************************|

 	msecs           	: count 	distribution
     	0 -> 1      	: 316  	|****************************************|

 	msecs           	: count 	distribution
     	0 -> 1      	: 255  	|****************************************|
     	2 -> 3      	: 0    	|                                    	|
     	4 -> 7      	: 0    	|                                    	|
     	8 -> 15     	: 1    	|                                    	|

Toa efa akaiky vahaolana isika. Ny fiasa ampiasaina hanamafisana / hanalana filaharana dia blk_mq_freeze_queue ΠΈ blk_mq_unfreeze_queue. Izy ireo dia ampiasaina rehefa ilaina ny manova ny filaharana fangatahana, izay mety hampidi-doza ho an'ny fangatahana amin'ity filaharana ity. Rehefa miantso blk_mq_freeze_queue() asa blk_freeze_queue_start() mitombo ny kaontera q->mq_freeze_depth. Aorian'izany dia miandry ny filaharana ny kernel blk_mq_freeze_queue_wait().

Ny fotoana ilaina hanesorana an'io filaharana io dia mitovy amin'ny fahatarana kapila satria miandry ny famitana ny asa milahatra rehetra ny kernel. Rehefa foana ny filaharana dia ampiharina ny fanovana fanovana. Aorian'izay no iantsoana azy blk_mq_unfreeze_queue(), mampihena ny kaontera freeze_depth.

Efa ampy ny fahafantarantsika izao mba hanitsiana ny toe-javatra. Ny baikon'ny trigger udevadm dia mahatonga ny firafitry ny fitaovana fanakanana hampiharina. Ireo toe-javatra ireo dia voalaza ao amin'ny fitsipika udev. Hitantsika hoe inona ny toe-javatra manamaivana ny filaharana amin'ny fiezahana hanova azy ireo amin'ny alΓ lan'ny sysfs na amin'ny fijerena ny code source kernel. Azontsika atao koa ny manandrana ny BCC utility soritry, izay hamoaka trace stack kernel sy userspace ho an'ny antso tsirairay mankany amin'ny terminal blk_freeze_queue, ohatra:

~# /usr/share/bcc/tools/trace blk_freeze_queue -K -U
PID 	TID 	COMM        	FUNC        	 
3809642 3809642 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	elevator_switch+0x29 [kernel]
    	elv_iosched_store+0x197 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

3809631 3809631 systemd-udevd   blk_freeze_queue
    	blk_freeze_queue+0x1 [kernel]
    	queue_requests_store+0xb6 [kernel]
    	queue_attr_store+0x5c [kernel]
    	sysfs_kf_write+0x3c [kernel]
    	kernfs_fop_write+0x125 [kernel]
    	__vfs_write+0x1b [kernel]
    	vfs_write+0xb8 [kernel]
    	sys_write+0x55 [kernel]
    	do_syscall_64+0x73 [kernel]
    	entry_SYSCALL_64_after_hwframe+0x3d [kernel]
    	__write_nocancel+0x7 [libc-2.23.so]
    	[unknown]

Mahalana no miova ny fitsipiky ny Udev ary matetika izany dia mitranga amin'ny fomba voafehy. Noho izany dia hitantsika fa na dia ny fampiharana ireo soatoavina efa napetraka aza dia miteraka fiakarana amin'ny fanemorana ny famindrana ny fangatahana avy amin'ny fampiharana mankany amin'ny disk. Mazava ho azy fa tsy fomba fanao tsara ny famoronana hetsika udev rehefa tsy misy fiovana eo amin'ny firafitry ny kapila (ohatra, ny fitaovana dia tsy mipetaka / tapaka). Na izany aza, afaka manampy ny kernel tsy hanao asa tsy ilaina isika ary hanamaivana ny filaharana fangatahana raha tsy ilaina izany. telo KELY Ankino hanitsy ny toe-javatra.

Famaranana

Ny eBPF dia fitaovana tena malefaka sy matanjaka. Tao amin'ny lahatsoratra dia nijery tranga iray azo ampiharina izahay ary nampiseho ampahany kely amin'izay azo atao. Raha liana amin'ny fampivoarana ny fampitaovana BCC ianao dia mendrika ny hojerena fampianarana ofisialy, izay mamaritra tsara ny fototra.

Misy fitaovana debugging sy profiling mahaliana hafa mifototra amin'ny eBPF. Ny iray tamin'izy ireo - bpftrace, izay ahafahanao manoratra tsipika tokana matanjaka sy fandaharana kely amin'ny fiteny mitovy amin'ny awk. iray hafa - ebpf_exporter, dia ahafahanao manangona metrika avo lenta sy avo lenta mivantana ao amin'ny mpizara prometheus anao, miaraka amin'ny fahafahana mahazo sary tsara tarehy sy fanairana mihitsy aza.

Source: www.habr.com

Add a comment