Hôm nay chúng tôi muốn nói về một số cập nhật mới nhất cho hệ thống Sherlock [đây là cụm hiệu suất cao tại Đại học Stanford - khoảng. trans.], giúp tăng tốc đáng kể việc liệt kê các tệp trong thư mục có số lượng mục nhập lớn.
Không giống như các bài viết thông thường, đây là báo cáo nội bộ về cách chúng tôi thường xuyên làm việc trên Sherlock để đảm bảo nó hoạt động tốt nhất cho người dùng. Chúng tôi hy vọng sẽ xuất bản nhiều bài viết như thế này trong tương lai.
Liệt kê nhiều tập tin mất thời gian
Tất cả bắt đầu với một câu hỏi hỗ trợ kỹ thuật từ người dùng. Ông báo cáo vấn đề rằng việc thực hiện ls
mất vài phút trong một thư mục với hơn 15 mục trong $SCRATCH
[thư mục chứa các tập tin tạm thời - khoảng. làn đường].
Hàng nghìn tệp trong một thư mục thường gây gánh nặng cho hệ thống tệp và chắc chắn không được khuyến khích. Người dùng biết điều này và thừa nhận rằng nó không tốt, nhưng đề cập rằng danh sách trên máy tính xách tay của anh ấy nhanh hơn Sherlock 1000 lần. Tất nhiên, điều này làm tổn thương chúng tôi. Vì vậy, chúng tôi đã nhìn sâu hơn.
Bởi vì ls trông đẹp
Chúng tôi đã xem xét những gì nó thực sự làm ls
khi liệt kê một thư mục và tại sao quá trình này lại mất nhiều thời gian như vậy. Trên hầu hết các bản phân phối hiện đại ls
theo mặc định nó chạy như ls --color=auto
, bởi vì mọi người đều thích màu sắc.
Nhưng màu sắc đẹp có giá của nó: cho mỗi tập tin ls
phải lấy thông tin về loại tệp, quyền, cờ, thuộc tính mở rộng và những thứ tương tự để chọn màu thích hợp.
Một giải pháp đơn giản cho vấn đề này là tắt hoàn toàn màu sắc trong ls, nhưng hãy tưởng tượng sự phẫn nộ của người dùng. Trong mọi trường hợp, bạn không nên lấy đi đầu ra màu sắc, chúng tôi không phải là quái vật.
Vì vậy, chúng tôi đã nhìn sâu hơn. ls
mục màu sắc thông qua biến môi trường LS_COLORS
, được thiết lập dircolors(1)
dựa trên tập tin cấu hình dir_colors(5)
... Đúng,
Chúng ta hãy xem xét kỹ hơn
Để xác định cách phối màu nào gây ra tình trạng chậm, chúng tôi đã tạo một môi trường thử nghiệm:
$ mkdir $SCRATCH/dont
$ touch $SCRATCH/dont/{1..10000} # don't try this at home!
$ time ls --color=always $SCRATCH/dont | wc -l
10000
real 0m12.758s
user 0m0.104s
sys 0m0.699s
12,7 giây cho 10 tệp, không tốt lắm.
Nhân tiện, chúng ta cần một lá cờ
--color=always
: mặc dù anh ấy quay sangls --color=auto
nhưngls
phát hiện khi nó không được kết nối với thiết bị đầu cuối (ví dụ: bằng đường ống hoặc chuyển hướng đầu ra) và tắt màu nếu được đặt thànhauto
. Anh chàng thông minh.
Vậy có chuyện gì mà lâu thế? Chúng tôi đã nhìn với strace
:
$ strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
44.21 0.186617 19 10000 lstat
42.60 0.179807 18 10000 10000 getxattr
12.19 0.051438 5 10000 capget
0.71 0.003002 38 80 getdents
0.07 0.000305 10 30 mmap
0.05 0.000217 12 18 mprotect
0.03 0.000135 14 10 read
0.03 0.000123 11 11 open
0.02 0.000082 6 14 close
[...]
Ôi: 10 cuộc gọi lstat()
, 10 cuộc gọi getxattr()
(tất cả đều thất bại vì môi trường của chúng tôi không có các thuộc tính mà tôi đang tìm kiếm), 10 cuộc gọi capget()
.
Chắc chắn điều này có thể được tối ưu hóa.
Thuộc tính khả năng? Không
Làm theo lời khuyên
$ eval $(dircolors -b | sed s/ca=[^:]*:/ca=:/)
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
98.95 0.423443 42 10000 lstat
0.78 0.003353 42 80 getdents
0.04 0.000188 10 18 mprotect
0.04 0.000181 6 30 mmap
0.02 0.000085 9 10 read
0.02 0.000084 28 3 mremap
0.02 0.000077 7 11 open
0.02 0.000066 5 14 close
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.427920 10221 6 total
real 0m8.160s
user 0m0.115s
sys 0m0.961s
Wow, tăng tốc lên tới 8 giây! Chúng tôi đã loại bỏ tất cả những cuộc gọi đắt tiền đó getxattr()
, và những thách thức capget()
cũng biến mất, tuyệt vời.
Nhưng vẫn có những cuộc gọi khó chịu lstat()
, Mặc dù…
Bạn cần bao nhiêu bông hoa?
Vì vậy, chúng tôi đã xem xét kỹ hơn LS_COLORS
.
Đầu tiên chúng tôi chỉ đơn giản là vô hiệu hóa biến này:
$ echo $LS_COLORS rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36: $ unset LS_COLORS $ echo $LS_COLORS $ time ls --color=always $SCRATCH/dont | wc -l 10000 real 0m13.037s user 0m0.077s sys 0m1.092s
Cái gì!?! Vẫn còn 13 giây?
Hóa ra là khi biến môi trường LS_COLORS
chỉ một trong các phần tử của nó không được xác định hoặc bị thiếu <type>=color:
, nó sử dụng cơ sở dữ liệu tích hợp theo mặc định và vẫn sử dụng màu sắc. Vì vậy, nếu bạn muốn tắt tính năng tô màu cho một loại tệp nhất định, bạn cần ghi đè nó bằng <type>=:
hoặc <type> 00
trong tập tin DIR_COLORS
.
Sau rất nhiều thử nghiệm và sai sót, chúng tôi đã thu hẹp phạm vi tìm kiếm của mình xuống mức này:
EXEC 00
SETUID 00
SETGID 00
CAPABILITY 00
được viết là
LS_COLORS='ex=00:su=00:sg=00:ca=00:'
Điều này có nghĩa là: không tô màu các tập tin theo thuộc tính.
, không phải bởi
Chúng tôi tăng tốc ls
Và nếu bạn không thực hiện bất kỳ kiểm tra nào trong số này thì hãy gọi lstat()
biến mất, và bây giờ nó là một vấn đề hoàn toàn khác:
$ export LS_COLORS='ex=00:su=00:sg=00:ca=00:'
$ time strace -c ls --color=always $SCRATCH/dont | wc -l
10000
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
63.02 0.002865 36 80 getdents
8.10 0.000368 12 30 mmap
5.72 0.000260 14 18 mprotect
3.72 0.000169 15 11 open
2.79 0.000127 13 10 read
[...]
------ ----------- ----------- --------- --------- ----------------
100.00 0.004546 221 6 total
real 0m0.337s
user 0m0.032s
sys 0m0.029s
0,3 giây trên danh sách 10 tệp, một bản ghi.
Đang thiết lập Sherlock
Từ 13 giây với cài đặt mặc định đến 0,3 giây với những điều chỉnh nhỏ LS_COLORS
có nghĩa là tăng tốc gấp 40 lần do không có setuid
/ setgid
và các tập tin thực thi được tô màu. Không phải là một mất mát lớn như vậy.
Tất nhiên, điều này hiện đã được định cấu hình trong Sherlock cho từng người dùng.
Nhưng nếu bạn muốn trả lại màu, bạn chỉ cần quay lại cài đặt mặc định:
$ unset LS_COLORS
Nhưng sau đó, trên các thư mục có nhiều tệp, hãy nhớ pha cà phê trong khi nó đang chạy ls
.
Nguồn: www.habr.com