Tá líon mór uirlisí ag Linux chun an eithne agus na feidhmchláir a dhífhabhtú. Bíonn tionchar diúltach ag an gcuid is mó díobh ar fheidhmíocht iarratais agus ní féidir iad a úsáid i dtáirgeadh.
Cúpla bliain ó shin bhí
Tá go leor fóntais feidhmchláir ann cheana féin a úsáideann eBPF, agus san Airteagal seo féachfaimid ar conas do áirgiúlacht próifílithe féin a scríobh bunaithe ar an leabharlann
Tá Ceph mall
Tá óstach nua curtha le braisle Ceph. Tar éis dúinn cuid de na sonraí a aistriú chuige, thugamar faoi deara go raibh an luas próiseála iarratais scríofa aige i bhfad níos ísle ná mar a bhí ar fhreastalaithe eile.
Murab ionann agus ardáin eile, bhain an t-óstach seo úsáid as bcache agus an eithne nua linux 4.15. Ba é seo an chéad uair a úsáideadh óstach den chumraíocht seo anseo. Agus ag an nóiméad sin bhí sé soiléir go bhféadfadh an fhréamh na faidhbe teoiriciúil rud ar bith.
Imscrúdú ar an Óstach
Let tús le breathnú ar cad a tharlaíonn taobh istigh den phróiseas ceph-osd. Chun seo a úsáidfimid
Insíonn an pictiúr dúinn go bhfuil an fheidhm fdatasync() chaith sé go leor ama ag seoladh iarratas chuig feidhmeanna cineálach_make_request(). Ciallaíonn sé seo gur dócha go bhfuil cúis na bhfadhbanna áit éigin lasmuigh den deamhan OSD féin. Is féidir é seo a bheith ar an eithne nó dioscaí. Léirigh an t-aschur iostat go raibh an-fholach i bpróiseáil iarratais ó dhioscaí bcache.
Agus an t-óstach á sheiceáil, fuair muid amach go n-ídíonn an deamhan systemd-udevd cuid mhór ama LAP - thart ar 20% ar roinnt cores. Is iompar aisteach é seo, mar sin ní mór duit a fháil amach cén fáth. Ós rud é go n-oibríonn Systemd-udevd le uevents, bheartaíomar breathnú orthu tríd monatóireacht a dhéanamh ar udevadm. Tharlaíonn sé go raibh líon mór imeachtaí athraithe ginte do gach feiste bloc sa chóras. Tá sé seo neamhghnách go leor, mar sin beidh orainn breathnú ar cad a ghineann na himeachtaí seo go léir.
Ag baint úsáide as Foireann Uirlisí BCC
Mar atá faighte amach againn cheana féin, caitheann an eithne (agus an deamhan ceph sa ghlao córais) go leor ama i cineálach_make_request(). Déanaimis iarracht luas na feidhme seo a thomhas. IN
De ghnáth oibríonn an ghné seo go tapa. Níl le déanamh aige ach an t-iarratas a chur ar aghaidh chuig scuaine tiománaí an ghléis.
Bcache is gléas casta é ina bhfuil trí dhiosca i ndáiríre:
- gléas tacaíochta (diosca i dtaisce), sa chás seo is HDD mall é;
- gléas taisce (diosca caching), seo deighilt amháin den fheiste NVMe;
- an gléas fíorúil bcache lena ritheann an feidhmchlár.
Tá a fhios againn go bhfuil tarchur iarratais mall, ach cé acu de na gléasanna seo? Déileálfaimid leis seo beagán níos déanaí.
Tá a fhios againn anois gur dócha go gcruthóidh imeachtaí fadhbanna. Níl sé chomh furasta cad is cúis lena nginiúint a fháil go díreach. Glacaimid leis gur bogearraí de chineál éigin é seo a sheoltar go tréimhsiúil. A ligean ar a fheiceáil cén cineál bogearraí a ritheann ar an gcóras ag baint úsáide as script execsnoop as an gcéanna
Mar shampla mar seo:
/usr/share/bcc/tools/execsnoop | tee ./execdump
Ní thaispeánfaimid an t-aschur iomlán execsnoop anseo, ach bhí cuma mar seo ar líne spéise amháin:
sh 1764905 5802 0 sudo arcconf getconfig 1 AD | grep Temperature | awk -F '[:/]' '{print $2}' | sed 's/^ ([0-9]*) C.*/1/'
Is é an tríú colún an PPID (PID tuismitheora) den phróiseas. Bhí an próiseas le PID 5802 ar cheann de na snáitheanna dár gcóras monatóireachta. Nuair a bhí cumraíocht an chórais monatóireachta á seiceáil, fuarthas paraiméadair earráideacha. Tógadh teocht an adapter HBA gach 30 soicind, atá i bhfad níos minice ná mar is gá. Tar éis an t-eatramh seiceála a athrú go heatramh níos faide, fuaireamar amach nár sheas an fhoighne próiseála iarratais ar an óstach seo amach a thuilleadh i gcomparáid le hóstach eile.
Ach níl sé soiléir fós cén fáth a raibh an gléas bcache chomh mall. D’ullmhaigh muid ardán tástála le cumraíocht chomhionann agus rinneamar iarracht an fhadhb a atáirgeadh trí fio ar bcache a rith, ag rith truicear udevadm go tréimhsiúil chun uevents a ghiniúint.
Uirlisí BCC-Bhunaithe a scríobh
Déanaimis iarracht fóntais shimplí a scríobh chun na glaonna is moille a rianú agus a thaispeáint cineálach_make_request(). Tá suim againn freisin in ainm an tiomántáin ar tugadh an fheidhm seo air.
Tá an plean simplí:
- Clár kprobe ar cineálach_make_request():
- Sábhálann muid an t-ainm diosca i gcuimhne, inrochtana tríd an argóint feidhme;
- Sábhálann muid an stampa ama.
- Clár créatúr le haghaidh filleadh ó cineálach_make_request():
- Faighimid an stampa ama reatha;
- Lorgaimid an stampa ama a shábháiltear agus cuirimid i gcomparáid é leis an gceann reatha;
- Má tá an toradh níos mó ná an ceann sonraithe, ansin aimsímid an t-ainm diosca shábháil agus é a thaispeáint ar an teirminéal.
Kprobes и próistí meicníocht brisphointe a úsáid chun an cód feidhme ar an eitilt a athrú. Is féidir leat léamh
Breathnaíonn an téacs eBPF taobh istigh den script python mar seo:
bpf_text = “”” # Here will be the bpf program code “””
Chun sonraí a mhalartú idir feidhmeanna, úsáideann cláir eBPF
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);
Anseo táimid ag clárú tábla hash ar a dtugtar p, le cineál eochair u64 agus luach cineáil struct data_t. Beidh an tábla ar fáil i gcomhthéacs ár gclár BPF. Cláraíonn an macra BPF_PERF_OUTPUT tábla eile ar a dtugtar imeachtaí, a úsáidtear le haghaidh
Agus moilleanna á dtomhas idir glaoch ar fheidhm agus filleadh uaithi, nó idir glaonna chuig feidhmeanna éagsúla, ní mór duit a chur san áireamh go gcaithfidh na sonraí a fuarthas a bheith bainteach leis an gcomhthéacs céanna. I bhfocail eile, ní mór duit cuimhneamh ar sheoladh comhthreomhar féideartha feidhmeanna. Tá an cumas againn an fhoighne a thomhas idir glao a chur ar fheidhm i gcomhthéacs próiseas amháin agus filleadh ón bhfeidhm sin i gcomhthéacs próisis eile, ach is dócha go bhfuil sé seo gan úsáid. Sampla maith a bheadh anseo
Ansin, ní mór dúinn an cód a scríobh a rithfidh nuair a thugtar an fheidhm atá á staidéar:
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);
}
Anseo cuirfear an chéad argóint den fheidhm a thugtar air in ionad an dara argóint
Tabharfar an fheidhm seo a leanas ar fhilleadh ó cineálach_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);
}
}
Tá an fheidhm seo cosúil leis an gceann roimhe seo: faighimid amach PID an phróisis agus an stampa ama, ach ní leithroinnimid cuimhne don struchtúr sonraí nua. Ina áit sin, déanaimid cuardach ar an tábla hash le haghaidh struchtúr atá ann cheana féin ag baint úsáide as an eochair == PID reatha. Má aimsítear an struchtúr, ansin faighimid amach ainm an phróisis reatha agus cuirimid leis é.
Is gá an t-aistriú dénártha a úsáidimid anseo chun an GID snáithe a fháil. siúd. PID den phríomhphróiseas a chuir tús leis an snáithe i gcomhthéacs a bhfuilimid ag obair. An fheidhm tugaimid
Nuair a bheidh an t-aschur chuig an teirminéal, níl suim againn sa snáithe faoi láthair, ach tá suim againn sa phríomhphróiseas. Tar éis dúinn an mhoill mar thoradh air a chur i gcomparáid le tairseach ar leith, rachaimid thar ár struchtúr dáta isteach sa spás úsáideora tríd an tábla imeachtaí, ina dhiaidh sin scriosaimid an iontráil ó p.
Sa script python a luchtóidh an cód seo, ní mór dúinn na tairseacha moille agus na haonaid ama a chur in ionad MIN_US agus FACTOR, a rachaimid trí na hargóintí:
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"
Anois ní mór dúinn an clár BPF a ullmhú trí
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")
Beidh orainn a chinneadh freisin struct data_t inár script, nó ní bheidh muid in ann aon rud a léamh:
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)]
Is í an chéim dheireanach ná sonraí a aschur chuig an teirminéal:
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()
Tá an script féin ar fáil ag
Ar deireadh! Anois feicimid gur glao stadála é an rud a d’fhéach cosúil le gléas cache stalla cineálach_make_request() le haghaidh diosca i dtaisce.
Déan tochailt isteach san Eithne
Cad é go díreach atá ag moilliú le linn tarchuir iarratais? Feicimid go dtarlaíonn an mhoill fiú roimh thús na cuntasaíochta iarratais, i.e. níl tús curtha fós le cuntas a thabhairt ar iarratas sonrach ar thuilleadh aschuir staidrimh ina leith (/proc/diosca nó iostat). Is féidir é seo a fhíorú go héasca trí iostat a rith agus an fhadhb a atáirgeadh, nó
Má táimid ar an fheidhm cineálach_make_request(), ansin feicfimid sula dtosaíonn an t-iarratas ar chuntasaíocht, go dtugtar dhá fheidhm eile. Ar dtús - seiceálacha_cineálacha_make_request_(), déanann sé seiceálacha ar dhlisteanacht an iarratais maidir le socruithe an diosca. Dara -
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));
Inti, fanann an eithne go scaoilfidh an scuaine. Déanaimis an mhoill a thomhas 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 | |
Tá an chuma ar an scéal go bhfuilimid gar do réiteach. Is iad na feidhmeanna a úsáidtear chun scuaine a reo/díreo
Is ionann an t-am a thógann sé an scuaine seo a ghlanadh agus foilsiú an diosca mar go bhfanann an t-eithne ar gach oibríocht scuaine a chur i gcrích. Nuair a bhíonn an scuaine folamh, cuirtear na hathruithe socruithe i bhfeidhm. Tar éis a dtugtar é
Anois tá a fhios againn go leor chun an scéal a cheartú. Is cúis leis an ordú truicear udevadm na socruithe don bhlocghléas a chur i bhfeidhm. Déantar cur síos ar na socruithe seo i rialacha udev. Is féidir linn a fháil amach cé na socruithe atá ag reo na scuaine trí iarracht a dhéanamh iad a athrú trí sysfs nó trí bhreathnú ar an gcód foinse eithne. Is féidir linn triail a bhaint as fóntais BCC freisin
~# /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]
Is annamh a athraíonn rialacha Udev agus de ghnáth tarlaíonn sé seo ar bhealach rialaithe. Mar sin feicimid go n-eascraíonn fiú na luachanna atá socraithe cheana féin a chur i bhfeidhm go mór leis an moill a bhaineann leis an iarratas a aistriú ón bhfeidhmchlár chuig an diosca. Ar ndóigh, ní dea-chleachtas é imeachtaí udev a ghiniúint nuair nach bhfuil aon athruithe ar chumraíocht an diosca (mar shampla, nach bhfuil an gléas gléasta/dícheangailte). Mar sin féin, is féidir linn cabhrú leis an eithne gan obair neamhriachtanach a dhéanamh agus an scuaine iarratais a reoite mura bhfuil gá leis.
Conclúid
Uirlis thar a bheith solúbtha agus chumhachtach is ea eBPF. San alt bhreathnaíomar ar chás praiticiúil amháin agus léirigh muid cuid bheag den méid is féidir a dhéanamh. Más spéis leat fóntais BCC a fhorbairt, is fiú breathnú air
Tá uirlisí dífhabhtaithe agus próifílithe suimiúla eile bunaithe ar eBPF. Ceann acu -
Foinse: will.com