Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC

Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC

Ang Linux adunay daghang mga himan alang sa pag-debug sa kernel ug mga aplikasyon. Kadaghanan kanila adunay negatibo nga epekto sa performance sa aplikasyon ug dili magamit sa produksiyon.

Pipila ka tuig ang milabay adunay laing himan ang naugmad - eBPF. Kini nagpaposible sa pagsubay sa kernel ug mga aplikasyon sa user nga adunay ubos nga overhead ug walay panginahanglan sa pagtukod pag-usab sa mga programa ug pagkarga sa mga module sa ikatulo nga partido ngadto sa kernel.

Adunay daghan na nga mga utility sa aplikasyon nga naggamit sa eBPF, ug sa kini nga artikulo atong tan-awon kung giunsa pagsulat ang imong kaugalingon nga profiling utility base sa librarya. PythonBCC. Ang artikulo gibase sa tinuod nga mga panghitabo. Magbalhin kami gikan sa problema aron ayohon aron ipakita kung giunsa magamit ang mga gamit sa piho nga mga sitwasyon.

Mahinay si Ceph

Usa ka bag-ong host ang gidugang sa Ceph cluster. Pagkahuman sa pagbalhin sa pipila ka mga datos niini, among namatikdan nga ang katulin sa pagproseso sa mga hangyo sa pagsulat niini labi ka ubos kaysa sa ubang mga server.

Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC
Dili sama sa ubang mga platform, kini nga host migamit bcache ug ang bag-ong linux 4.15 kernel. Kini ang unang higayon nga gigamit dinhi ang usa ka host niini nga configuration. Ug nianang higayuna klaro nga ang gamut sa problema mahimo nga bisan unsa nga teoretikal.

Pag-imbestigar sa Host

Magsugod kita pinaagi sa pagtan-aw kung unsa ang mahitabo sa sulod sa proseso sa ceph-osd. Alang niini atong gamiton perf ΠΈ flamescope (dugang bahin sa imong mabasa dinhi):

Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC
Ang hulagway nagsulti kanato nga ang function fdatasync() migahin og daghang panahon sa pagpadala sa usa ka hangyo sa mga gimbuhaton generic_make_request(). Kini nagpasabot nga lagmit ang hinungdan sa mga problema anaa sa gawas sa osd daemon mismo. Mahimo kini nga kernel o mga disk. Ang iostat output nagpakita sa taas nga latency sa pagproseso sa mga hangyo pinaagi sa bcache disks.

Kung gisusi ang host, among nahibal-an nga ang systemd-udevd daemon nag-ut-ot sa daghang oras sa CPU - mga 20% sa daghang mga cores. Katingad-an kini nga pamatasan, busa kinahanglan nimo nga mahibal-an kung ngano. Tungod kay ang Systemd-udevd nagtrabaho sa mga uevents, nakahukom kami nga tan-awon kini udevadm monitor. Kini nahimo nga daghang gidaghanon sa mga panghitabo sa pagbag-o ang nahimo alang sa matag block device sa sistema. Talagsa ra kini, mao nga kinahanglan naton tan-awon kung unsa ang hinungdan sa tanan nga mga panghitabo.

Gamit ang BCC Toolkit

Sa ato nang nahibal-an, ang kernel (ug ang ceph daemon sa system call) naggugol ug daghang oras sa generic_make_request(). Atong sulayan ang pagsukod sa gikusgon niini nga function. SA BCC Adunay na usa ka talagsaon nga gamit - function. Atong masubay ang daemon pinaagi sa PID niini nga adunay 1 segundos nga agwat tali sa mga output ug output ang resulta sa milliseconds.

Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC
Kini nga bahin kasagarang molihok dayon. Ang tanan nga gihimo niini mao ang pagpasa sa hangyo sa pila sa drayber sa aparato.

Bcache mao ang usa ka komplikado nga himan nga sa pagkatinuod naglangkob sa tulo ka mga disk:

  • backing device (cached disk), sa kini nga kaso kini usa ka hinay nga HDD;
  • caching device (caching disk), dinhi kini usa ka partisyon sa NVMe device;
  • ang bcache virtual device nga gigamit sa aplikasyon.

Nahibal-an namon nga hinay ang pagpadala sa hangyo, apan hain niini nga mga aparato? Ato kining atubangon sa ulahi.

Nahibal-an na namon nga ang mga uevent lagmit nga hinungdan sa mga problema. Ang pagpangita kung unsa gyud ang hinungdan sa ilang henerasyon dili kaayo kadali. Atong isipon nga kini usa ka matang sa software nga gilansad matag karon ug unya. Atong tan-awon kung unsang klase sa software ang nagdagan sa sistema gamit ang script execsnoop gikan sa samang BCC utility kit. Ato kining padaganon ug ipadala ang output sa usa ka file.

Pananglitan sama niini:

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

Dili namo ipakita ang bug-os nga output sa execsnoop dinhi, apan ang usa ka linya sa interes kanamo ingon niini:

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

Ang ikatulo nga kolum mao ang PPID (parent PID) sa proseso. Ang proseso sa PID 5802 nahimo nga usa sa mga hilo sa among monitoring system. Kung gisusi ang pagsumpo sa sistema sa pag-monitor, nakit-an ang mga sayup nga mga parameter. Ang temperatura sa HBA adapter gikuha matag 30 segundos, nga mas kanunay kay sa gikinahanglan. Pagkahuman sa pagbag-o sa agwat sa tseke sa usa ka mas taas, among nahibal-an nga ang latency sa pagproseso sa hangyo sa kini nga host wala na makita kung itandi sa ubang mga host.

Apan dili pa klaro kung ngano nga ang aparato sa bcache hinay kaayo. Nag-andam kami usa ka plataporma sa pagsulay nga adunay parehas nga pagsumpo ug gisulayan nga kopyahon ang problema pinaagi sa pagpadagan sa fio sa bcache, matag karon nga pagpadagan sa udevadm trigger aron makamugna mga uevents.

Pagsulat sa BCC-Based Tools

Atong sulayan ang pagsulat sa usa ka yano nga gamit sa pagsubay ug pagpakita sa pinakahinay nga mga tawag generic_make_request(). Interesado usab kami sa ngalan sa drive diin kini nga function gitawag.

Simple ra ang plano:

  • Pagrehistro kprobe sa generic_make_request():
    • Gitipigan namon ang ngalan sa disk sa memorya, nga ma-access pinaagi sa argumento sa function;
    • Gitipigan namon ang timestamp.

  • Pagrehistro kretprobe alang sa pagbalik gikan sa generic_make_request():
    • Atong makuha ang kasamtangan nga timestamp;
    • Among pangitaon ang na-save nga timestamp ug itandi kini sa kasamtangan;
    • Kung ang resulta mas dako kay sa gitakda, nan atong makita ang naluwas nga ngalan sa disk ug ipakita kini sa terminal.

Kprobes ΠΈ kretprobes gamita ang mekanismo sa breakpoint aron usbon ang function code sa langaw. Makabasa ka dokumentasyon ΠΈ maayo artikulo bahin niini nga topiko. Kung imong tan-awon ang code sa lainlaing mga utilities sa BCC, unya imong makita nga sila adunay parehas nga istruktura. Busa niining artikuloha atong laktawan ang pag-parse sa mga argumento sa script ug magpadayon sa programa sa BPF mismo.

Ang eBPF nga teksto sa sulod sa script sa python ingon niini:

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

Sa pagbayloay sa datos tali sa mga gimbuhaton, gigamit ang mga programa sa eBPF hash nga mga lamesa. Amo man ang himuon. Atong gamiton ang proseso nga PID ingon nga yawe, ug ipasabut ang istruktura ingon nga kantidad:

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);

Dinhi nagparehistro kami usa ka lamesa sa hash nga gitawag p, nga adunay key type u64 ug usa ka bili sa tipo struct data_t. Ang lamesa mahimong magamit sa konteksto sa among programa sa BPF. Ang BPF_PERF_OUTPUT macro nagparehistro sa laing lamesa nga gitawag mga panghitabo, nga gigamit alang sa pagpadala sa datos ngadto sa user space.

Kung gisukod ang mga paglangan tali sa pagtawag sa usa ka function ug pagbalik gikan niini, o tali sa mga tawag sa lainlaing mga gimbuhaton, kinahanglan nimo nga tagdon nga ang nadawat nga datos kinahanglan nga nahisakop sa parehas nga konteksto. Sa laing pagkasulti, kinahanglan nimong hinumdoman ang bahin sa posible nga managsama nga paglansad sa mga gimbuhaton. Kita adunay katakus sa pagsukod sa latency tali sa pagtawag sa usa ka function sa konteksto sa usa ka proseso ug pagbalik gikan niana nga function sa konteksto sa laing proseso, apan kini lagmit walay kapuslanan. Usa ka maayong panig-ingnan dinhi gamit sa biolatency, diin ang hash nga yawe sa lamesa gibutang sa usa ka pointer sa hangyo sa istruktura, nga nagpakita sa usa ka hangyo sa disk.

Sunod, kinahanglan natong isulat ang code nga modagan kung ang function nga gitun-an gitawag:

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);
}

Dinhi ang unang argumento sa gitawag nga function ilisan isip ikaduhang argumento generic_make_request(). Pagkahuman niini, makuha namon ang PID sa proseso sa konteksto diin kami nagtrabaho, ug ang karon nga timestamp sa nanosecond. Gisulat namo kining tanan sa bag-ong gipili struct data_t data. Nakuha namon ang ngalan sa disk gikan sa istruktura bio, nga gipasa sa dihang nagtawag generic_make_request(), ug i-save kini sa parehas nga istruktura nga data. Ang katapusan nga lakang mao ang pagdugang usa ka entry sa hash table nga gihisgutan sa sayo pa.

Ang mosunod nga function tawgon sa pagbalik gikan sa 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);
    }
}

Kini nga function susama sa nauna: nahibal-an namon ang PID sa proseso ug ang timestamp, apan ayaw paggahin og memorya alang sa bag-ong istruktura sa datos. Hinunoa, atong pangitaon ang hash table alang sa naa na nga istruktura gamit ang yawe == kasamtangan nga PID. Kung makit-an ang istruktura, nan mahibal-an namon ang ngalan sa proseso sa pagdagan ug idugang kini.

Ang binary shift nga atong gigamit dinhi gikinahanglan aron makuha ang thread GID. mga. PID sa nag-unang proseso nga nagsugod sa hilo sa konteksto diin kami nagtrabaho. Ang function nga atong gitawag bpf_get_current_pid_tgid() ibalik ang GID sa thread ug ang PID niini sa usa ka 64-bit nga kantidad.

Kung nag-output sa terminal, dili kami interesado karon sa hilo, apan interesado kami sa panguna nga proseso. Pagkahuman sa pagtandi sa resulta nga paglangan sa usa ka gihatag nga sukaranan, gipasa namon ang among istruktura nga data ngadto sa user space pinaagi sa lamesa mga panghitabo, pagkahuman atong tangtangon ang entry gikan sa p.

Sa script sa python nga mag-load niini nga code, kinahanglan natong ilisan ang MIN_US ug FACTOR sa mga delay threshold ug mga yunit sa oras, nga atong ipasa sa mga argumento:

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"

Karon kinahanglan namong andamon ang programa sa BPF pinaagi sa BPF macro ug pagrehistro sa mga sampol:

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")

Kinahanglan usab naton nga mahibal-an struct data_t sa among script, kung dili, dili kami makabasa bisan unsa:

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)]

Ang katapusang lakang mao ang pag-output sa datos sa 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()

Ang script mismo anaa sa GItHub. Atong sulayan ang pagpadagan niini sa usa ka test platform diin ang fio nagdagan, pagsulat sa bcache, ug tawagan ang udevadm monitor:

Gikan sa Taas nga Ceph Latency hangtod sa Kernel Patch gamit ang eBPF/BCC
Sa kataposan! Karon atong nakita nga ang hitsura sa usa ka stalling bcache device sa pagkatinuod usa ka stalling nga tawag generic_make_request() alang sa usa ka cached disk.

Pagkalot sa Kernel

Unsa man gyud ang naghinay sa panahon sa pagpadala sa hangyo? Nakita namon nga ang paglangan mahitabo bisan sa wala pa magsugod ang accounting sa hangyo, i.e. accounting sa usa ka piho nga hangyo alang sa dugang nga output sa statistics niini (/proc/diskstats o iostat) wala pa magsugod. Kini dali nga mapamatud-an pinaagi sa pagpadagan sa iostat samtang gi-reproduce ang problema, o BCC script biolatency, nga gibase sa pagsugod ug pagtapos sa hangyo nga accounting. Walay usa niini nga mga utilities ang magpakita sa mga problema alang sa mga hangyo sa cached disk.

Kung atong tan-awon ang function generic_make_request(), unya atong makita nga sa dili pa magsugod ang hangyo sa accounting, duha pa ka mga function ang gitawag. Una- generic_make_request_checks(), nagpahigayon mga pagsusi sa pagkalehitimo sa hangyo bahin sa mga setting sa disk. Ikaduha - blk_queue_enter(), nga adunay usa ka makapaikag nga hagit wait_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));

Diha niini, ang kernel naghulat alang sa pila nga mag-unfreeze. Atong sukdon ang pagkalangan 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    	|                                    	|

Morag duol na mi sa solusyon. Ang mga gimbuhaton nga gigamit sa pag-freeze/pag-unfreeze sa usa ka pila mao ang blk_mq_freeze_queue ΠΈ blk_mq_unfreeze_queue. Gigamit kini kung kinahanglan nga usbon ang mga setting sa pila sa hangyo, nga mahimo’g peligro alang sa mga hangyo sa kini nga pila. Sa dihang nanawag blk_mq_freeze_queue() paglihok blk_freeze_queue_start() ang counter gidugangan q->mq_freeze_depth. Pagkahuman niini, ang kernel maghulat alang sa pila nga wala’y sulod blk_mq_freeze_queue_wait().

Ang oras nga gikinahanglan aron malimpyohan kini nga pila katumbas sa latency sa disk samtang ang kernel naghulat nga makompleto ang tanan nga nakapila nga operasyon. Kung walay sulod ang pila, ang mga pagbag-o sa mga setting magamit. Human nga kini gitawag blk_mq_unfreeze_queue(), pagminus sa counter freeze_depth.

Karon igo na ang among nahibal-an aron matul-id ang kahimtang. Ang udevadm trigger command hinungdan sa mga setting alang sa block device nga i-apply. Kini nga mga setting gihulagway sa mga lagda sa udev. Makita nato kung unsang mga setting ang nagyelo sa pila pinaagi sa pagsulay sa pag-usab niini pinaagi sa sysfs o pinaagi sa pagtan-aw sa kernel source code. Mahimo usab natong sulayan ang BCC utility pagsubay, nga magpagawas sa kernel ug userspace stack traces alang sa matag tawag sa terminal blk_freeze_queuesama pananglit:

~# /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]

Ang mga lagda sa Udev panagsa ra mausab ug kasagaran kini mahitabo sa kontroladong paagi. Mao nga nakita namon nga bisan ang pagpadapat sa natakda na nga mga kantidad hinungdan sa usa ka spike sa paglangan sa pagbalhin sa hangyo gikan sa aplikasyon ngadto sa disk. Siyempre, ang paghimo sa mga panghitabo sa udev kung wala’y mga pagbag-o sa pagsumpo sa disk (pananglitan, ang aparato wala gi-mount / gidiskonekta) dili maayo nga praktis. Bisan pa, makatabang kami sa kernel nga dili makahimo sa wala kinahanglana nga trabaho ug i-freeze ang queue sa hangyo kung dili kinahanglan. Tulo gamay pasalig tarong ang sitwasyon.

Panapos

Ang eBPF kay flexible ug gamhanan kaayo nga himan. Sa artikulo among gitan-aw ang usa ka praktikal nga kaso ug gipakita ang gamay nga bahin sa kung unsa ang mahimo. Kung interesado ka sa pagpalambo sa mga gamit sa BCC, angayan nga tan-awon opisyal nga panudlo, nga naghulagway sa mga sukaranan nga maayo.

Adunay uban pang makapaikag nga pag-debug ug mga gamit sa profiling base sa eBPF. Usa kanila- bpftrace, nga nagtugot kanimo sa pagsulat sa gamhanan nga one-liners ug gagmay nga mga programa sa awk-like nga pinulongan. Laing- ebpf_exporter, nagtugot kanimo sa pagkolekta sa ubos nga lebel, taas nga resolusyon nga mga sukatan direkta ngadto sa imong prometheus server, nga adunay abilidad sa ulahi nga makakuha og nindot nga mga visualization ug bisan mga alerto.

Source: www.habr.com

Idugang sa usa ka comment