Làm cách nào để sử dụng không gian hoán đổi chỉ trong trường hợp khẩn cấp?


41

Tôi có một máy tính xách tay Debian (Buster) với RAM 8 GB và trao đổi 16 GB. Tôi đang chạy một nhiệm vụ rất dài. Điều này có nghĩa là máy tính xách tay của tôi đã bị bỏ lại trong sáu ngày qua trong khi nó lướt qua.

Trong khi làm điều này, tôi định kỳ cần sử dụng máy tính xách tay của tôi như một máy tính xách tay. Đây không phải là một vấn đề; tác vụ chạy dài bị ràng buộc I / O, hoạt động thông qua các thứ trên đĩa cứng USB và không tốn nhiều RAM (<200 MB) hoặc CPU (<4%).

Vấn đề là khi tôi trở lại máy tính xách tay của mình sau vài giờ, nó sẽ rất chậm chạp và có thể mất 30 phút để trở lại bình thường. Điều này tệ đến mức các trình giám sát sự cố đánh dấu các ứng dụng tương ứng của chúng bị đóng băng (đặc biệt là các cửa sổ trình duyệt) và mọi thứ bắt đầu không chính xác.

Nhìn vào màn hình hệ thống, 2,5 GB được sử dụng khoảng một nửa được chuyển sang trao đổi. Tôi đã xác nhận đây là sự cố bằng cách xóa không gian hoán đổi ( swapoff /dev/sda8). Nếu tôi để nó mà không có không gian hoán đổi, nó sẽ hoạt động trở lại gần như ngay lập tức ngay cả sau 24 giờ. Với trao đổi, thực tế nó là một viên gạch trong năm phút đầu tiên chỉ còn lại sáu giờ. Tôi đã xác nhận rằng mức sử dụng bộ nhớ không bao giờ vượt quá 3 GB ngay cả khi tôi đi vắng.

Tôi đã cố gắng giảm swappiness ( xem thêm: Wikipedia ) để giá trị của 100, nhưng vấn đề vẫn còn tồn tại. Có vẻ như sau một ngày không hoạt động, hạt nhân tin rằng toàn bộ GUI không còn cần thiết nữa và xóa sạch nó khỏi RAM (hoán đổi nó sang đĩa). Nhiệm vụ chạy dài là đọc qua một cây tệp lớn và đọc mọi tệp. Vì vậy, nó có thể là kernel bị nhầm lẫn khi nghĩ rằng bộ nhớ đệm sẽ giúp. Nhưng trong một lần quét USB HD 2 TB với ~ 1 tỷ tên tệp, RAM GB thêm sẽ không giúp hiệu năng nhiều. Đây là một máy tính xách tay giá rẻ với ổ cứng chậm chạp. Nó chỉ đơn giản là không thể tải dữ liệu trở lại vào RAM đủ nhanh.

Làm thế nào tôi có thể bảo Linux chỉ sử dụng không gian hoán đổi trong trường hợp khẩn cấp? Tôi không muốn chạy mà không trao đổi. Nếu có điều gì đó bất ngờ xảy ra và HĐH đột nhiên cần thêm vài GB thì tôi không muốn các tác vụ bị giết và muốn bắt đầu sử dụng trao đổi. Nhưng hiện tại, nếu tôi bật tính năng trao đổi, máy tính xách tay của tôi không thể được sử dụng khi tôi cần.

Định nghĩa chính xác của "trường hợp khẩn cấp" có thể là vấn đề cần tranh luận. Nhưng để làm rõ ý tôi muốn nói: Trường hợp khẩn cấp sẽ là nơi hệ thống bị bỏ lại mà không có lựa chọn nào khác ngoài việc hoán đổi hoặc tiêu diệt các quá trình.


Trường hợp khẩn cấp là gì? - Bạn có thực sự phải hỏi không? ... Tôi hy vọng bạn không bao giờ thấy mình trong một tòa nhà đang cháy!

Tôi không thể định nghĩa mọi thứ có thể tạo thành trường hợp khẩn cấp trong câu hỏi này. Nhưng ví dụ, trường hợp khẩn cấp có thể là khi hạt nhân bị đẩy vào bộ nhớ đến mức nó đã bắt đầu giết các quá trình với OOM Killer . Trường hợp khẩn cấp KHÔNG phải là khi kernel nghĩ rằng nó có thể cải thiện hiệu suất bằng cách sử dụng trao đổi.


Chỉnh sửa cuối cùng: Tôi đã chấp nhận một câu trả lời thực hiện chính xác những gì tôi đã yêu cầu ở cấp hệ điều hành. Độc giả tương lai cũng nên lưu ý các câu trả lời cung cấp giải pháp cấp ứng dụng.


11
Xác định "khẩn cấp" và nói điều gì đó khác biệt như thế nào với bất kỳ tình huống thông thường nào khi trao đổi sẽ được sử dụng.
Kusalananda

4
Tôi muốn biết nếu bạn muốn xác định bằng cách nào đó một loại "sự kiện khẩn cấp" ngoài giới hạn đặc biệt sẽ cho phép hạt nhân sử dụng trao đổi, nhưng trao đổi đó sẽ không được sử dụng. AFAIK phân trang bộ nhớ là thứ gì đó chậm và chỉ được thực hiện "trong trường hợp khẩn cấp", và điều "swappiness" là điều duy nhất bạn có thể sử dụng để điều chỉnh hành vi này với (nhưng tôi không phải là người dùng Linux).
Kusalananda

2
Không, điều đó không đúng. Nó không chỉ được thực hiện trong trường hợp khẩn cấp. Ít nhất tôi nghĩ rằng câu hỏi của tôi đã nói rõ rằng tôi chỉ sử dụng 3 GB trong số 8GB ... Đó không phải là trường hợp khẩn cấp nhưng dù sao thì hạt nhân cũng bị tráo đổi. Tôi đề nghị bạn đọc lên về swappiness và các chủ đề xung quanh. Có khá nhiều cuộc thảo luận về các lý do khác nhau để hoán đổi. Thật hợp lý khi tôi yêu cầu một khái niệm không tồn tại trong kernel, nhưng lý do của tôi để yêu cầu nó là hợp lý hợp lý ..
Philip Couling

4
Tôi nhận ra lời khuyên luôn luôn là "không bao giờ chạy mà không trao đổi". Nhưng kích thước bộ nhớ đã vượt quá tốc độ đọc / ghi của ổ cứng (HDD không phải SSD) có nghĩa là trao đổi ngày càng là một ý tưởng tồi. Có cảm giác như một số người tin rằng RAM 8GB + trao đổi 8GB sẽ thực hiện 16GB RAM + 0 trao đổi. Nếu nó thực sự làm thì có gì đó rất sai với kernel Linux.
Philip Couling

7
@Philip Couling: Không, vấn đề là RAM 16 GB + 16 GB trao đổi sẽ vượt trội hơn 16 GB và 0 trao đổi - đặc biệt là khi mã của bạn cần 17 GB bộ nhớ :-)
jamesqf

Câu trả lời:


11

Có một sự hoán đổi lớn như vậy ngày nay thường là một ý tưởng tồi. Vào thời điểm HĐH đổi chỗ chỉ vài GB bộ nhớ để trao đổi, hệ thống của bạn đã bò đến chết (giống như những gì bạn thấy)

Tốt hơn là sử dụng zramvới một phân vùng trao đổi sao lưu nhỏ . Nhiều hệ điều hành như ChromeOS, Android và các bản phân phối Linux khác nhau đã bật zram theo mặc định trong nhiều năm, đặc biệt là đối với các hệ thống có ít RAM hơn. Nó nhanh hơn nhiều so với trao đổi trên ổ cứng và bạn có thể cảm nhận rõ ràng khả năng phản hồi của hệ thống trong trường hợp này. Ít hơn trên một ổ SSD, nhưng theo kết quả điểm chuẩn ở đây, nó vẫn có vẻ nhanh hơn ngay cả với thuật toán lzo mặc định. Bạn có thể thay đổi thành lz4 để có hiệu suất cao hơn với tỷ lệ nén ít hơn một chút. Tốc độ giải mã của nó nhanh hơn gần 5 lần so với lzo dựa trên điểm chuẩn chính thức

Cũng có zswapmặc dù tôi chưa bao giờ sử dụng nó. Có lẽ đáng để thử và so sánh cái nào tốt hơn cho các ứng dụng của bạn

Sau đó, một đề xuất khác là giảm mức độ ưu tiên của các quy trình ràng buộc IO đó và có thể để một thiết bị đầu cuối chạy ở mức ưu tiên cao hơn để bạn có thể chạy các lệnh trên nó ngay lập tức ngay cả khi hệ thống đang tải cao

đọc thêm


Để tôi hiểu, bạn đang nói rằng tôi có thể tạo một zramthiết bị khối, sử dụng nó như trao đổi, với trao đổi ưu tiên thấp hơn như phân vùng ổ cứng?
Philip Couling

@PhilipCouling nếu bạn đang sử dụng ổ cứng thì có, chắc chắn bạn nên sử dụng zram hoặc các giải pháp tương tự. Mức độ ưu tiên của trao đổi phải thấp hơn zram, để Linux cố gắng sử dụng hết zram trước, sau đó nó sẽ xem xét trao đổi. Nếu bạn sử dụng Ubuntu thì gói zram-config đã đảm nhiệm các cài đặt ưu tiên cho bạn
phuclv

3
Tôi chấp nhận câu trả lời này vì nó dường như làm chính xác những gì tôi đã yêu cầu. Nếu tôi vẫn bật hoán đổi 16 GB ở mức ưu tiên giảm, thì kernel sẽ chỉ sử dụng nó khi zswap đã hết. IE: "trong trường hợp khẩn cấp". Lưu ý trên debian-buster, điều này rất dễ cài đặt, chỉ đơn giản bằng cách cài đặt các công cụ zram.
Philip Couling

25

Một cách khắc phục là đảm bảo bộ điều khiển cgroup bộ nhớ được bật (tôi nghĩ rằng nó được mặc định trong các hạt nhân gần đây, nếu không bạn sẽ cần thêm cgroup_enable=memoryvào dòng lệnh kernel). Sau đó, bạn có thể chạy tác vụ chuyên sâu I / O của mình trong một nhóm có giới hạn bộ nhớ, điều này cũng giới hạn số lượng bộ nhớ cache mà nó có thể tiêu thụ.

Nếu bạn đang sử dụng systemd, bạn có thể đặt +MemoryAccounting=yesMemoryHigh/ MemoryMaxhoặc MemoryLimit(tùy thuộc vào nếu bạn đang sử dụng cgroup v1 hoặc v2) trong đơn vị hoặc một lát có chứa nó. Nếu đó là một lát, bạn có thể sử dụng systemd-runđể chạy chương trình trong lát.

Ví dụ đầy đủ từ một trong các hệ thống của tôi để chạy Firefox với giới hạn bộ nhớ. Lưu ý điều này sử dụng cgroups v2 và được thiết lập là người dùng của tôi, không phải root (một trong những lợi thế của v2 so với v1 là việc ủy ​​thác điều này cho không root là an toàn, vì vậy systemd thực hiện điều đó).

$ systemctl --user cat mozilla.slice 
# /home/anthony/.config/systemd/user/mozilla.slice
[Unit]
Description=Slice for Mozilla apps
Before=slices.target

[Slice]
MemoryAccounting=yes
MemoryHigh=5G
MemoryMax=6G

$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/firefox &
$ systemd-run --user --slice mozilla.slice --scope -- /usr/bin/thunderbird &

Tôi tìm thấy để có được một người dùng làm việc tôi phải sử dụng một lát. Hệ thống một hoạt động chỉ bằng cách đặt các tùy chọn trong tệp dịch vụ (hoặc sử dụng systemctl set-propertytrên dịch vụ).

Đây là một dịch vụ ví dụ (sử dụng cgroup v1), lưu ý hai dòng cuối cùng. Đây là một phần của thể hiện hệ thống (pid = 1).

[Unit]
Description=mount S3QL filesystem
Requires=network-online.target
After=network-online.target

[Install]
WantedBy=multi-user.target

[Service]
Type=forking
User=s3ql-user
Group=s3ql-user
LimitNOFILE=20000
ExecStartPre=+/bin/sh -c 'printf "S3QL_CACHE_SIZE=%%i\n" $(stat -c "%%a*%%S*.90/1024" -f /srv/s3ql-cache/ | bc) > /run/local-s3ql-env'
ExecStartPre=/usr/bin/fsck.s3ql  --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo  --log none «REDACTED»
EnvironmentFile=-/run/local-s3ql-env
ExecStart=/usr/bin/mount.s3ql --keep-cache --cachedir /srv/s3ql-cache/fs1 --authfile /etc/s3ql-authinfo --cachesize ${S3QL_CACHE_SIZE} --threads 4
ExecStop=/usr/bin/umount.s3ql /mnt/S3QL/
TimeoutStopSec=2m
MemoryAccounting=yes
MemoryLimit=1G

Tài liệu là trong systemd.resource-control(5).


1
Bạn không thể làm một cái gì đó có thể so sánh và di động chỉ bằng cách sử dụng ulimit?
Old Pro

1
@OldPro không thực sự. Đầu tiên, AFAIK không phải là một vấn đề lớn về tổng mức sử dụng bộ nhớ bao gồm cả bộ đệm trang (đây là mức sử dụng đang trở nên quá mức ở đây). Thứ hai, ulimit cho bộ nhớ là theo quy trình, các nhóm hoạt động ngay cả khi tác vụ chạy dài.
derobert

Tôi nghĩ rằng lý do kế toán bộ nhớ được bật theo mặc định trên các hệ thống mới hơn là do sự thay đổi trong systemdphiên bản 238 .
nguồn

1
@sourcejedi tương đối gần đây. Khi bộ điều khiển bộ nhớ được giới thiệu lần đầu tiên, chỉ cần có sẵn nó (thậm chí không sử dụng) có chi phí hiệu năng đủ lớn để một số distro ít nhất vô hiệu hóa nó theo mặc định và bạn phải truyền đối số dòng lệnh kernel đó để kích hoạt nó. Các vấn đề về hiệu năng đã được khắc phục, do đó đã thay đổi và gần đây systemd cũng kích hoạt nó theo mặc định.
derobert

14

Có vẻ như sau một ngày không hoạt động, hạt nhân tin rằng toàn bộ GUI không còn cần thiết nữa và xóa sạch nó khỏi RAM (hoán đổi nó sang đĩa).

Hạt nhân đang thực hiện The Right Thing ™ tin vào điều đó. Tại sao nó sẽ giữ 1 bộ nhớ không sử dụng trong RAM và vì vậy về cơ bản sẽ lãng phí nó thay vì sử dụng nó làm bộ nhớ cache hoặc một cái gì đó?

Tôi không nghĩ rằng nhân Linux là các trang hoán đổi một cách vô cớ hoặc dự đoán, vì vậy nếu nó phải lưu trữ một thứ khác trên RAM, do đó cải thiện hiệu suất của tác vụ chạy dài của bạn hoặc ít nhất là với mục tiêu này.

Nếu bạn biết khi nào bạn cần sử dụng lại máy tính xách tay của mình trước, bạn có thể sử dụng atlệnh (hoặc crontab) để lên lịch dọn dẹp trao đổi ( swapoff -a;swapon -a).

Vì việc dọn dẹp trao đổi có thể là quá mức cần thiết và thậm chí kích hoạt trình diệt OOM nếu vì một lý do nào đó, không phải mọi thứ đều phù hợp với RAM, bạn có thể chỉ "tháo gỡ" 2 mọi thứ liên quan đến các ứng dụng đang chạy mà bạn muốn hồi sinh.

Một cách để làm điều đó là gắn một trình gỡ lỗi như gdbtừng quy trình bị ảnh hưởng và kích hoạt một thế hệ kết xuất lõi:

# gdb -p <pid>
...
generate-core-dump /dev/null
...
quit

Như bạn đã viết, ứng dụng chạy dài của bạn không sử dụng lại dữ liệu mà nó đọc sau lần vượt qua ban đầu, vì vậy bạn đang ở trong một trường hợp cụ thể trong đó bộ nhớ đệm dài hạn không hữu ích. Sau đó bỏ qua bộ đệm bằng cách sử dụng I / O trực tiếp như được đề xuất bởi Will Crawford sẽ là một cách giải quyết tốt.

Ngoài ra, bạn có thể thường xuyên xóa bộ đệm của tệp bằng cách lặp lại 1hoặc 3vào /proc/sys/vm/drop_cachestệp giả trước khi HĐH nghĩ rằng đó là một ý tưởng tốt để trao đổi các ứng dụng và môi trường GUI của bạn.

Xem Làm thế nào để bạn làm trống bộ đệm và bộ đệm trên hệ thống Linux? để biết chi tiết.

1 Không được sử dụng theo nghĩa: không được sử dụng tích cực hơn trong một khoảng thời gian đáng kể, bộ nhớ vẫn có liên quan đến chủ sở hữu của nó.
2 Đặt lại các trang RAM được lưu trữ trên vùng trao đổi.


2
Cảm ơn những suy nghĩ về nguyên nhân có thể. Tôi đã thêm một chút vào câu hỏi vì nó có thể có liên quan. Tôi tự hỏi liệu có cách nào để giảm mức độ ưu tiên của bộ nhớ đệm đối với bộ nhớ của ứng dụng hay không.
Philip Couling

5
"Tôi không nghĩ rằng nhân Linux là các trang bị hoán đổi một cách vô cớ hoặc dự đoán nên nếu nó làm điều đó, thì đó phải là để lưu trữ một cái gì đó khác trên RAM, do đó cải thiện hiệu suất." - Tôi nghĩ cách diễn đạt này hơi mơ hồ. Nhân chắc chắn sẽ viết các trang để trao đổi, bất cứ khi nào nó có cơ hội (ví dụ: có ít I / O đĩa). Tuy nhiên, nó sẽ không loại bỏ chúng khỏi RAM. Bằng cách đó, bạn có cả hai thế giới tốt nhất: nếu bạn nhanh chóng cần những trang đó một lần nữa, chúng đã có RAM và không có gì để làm. Nếu trường hợp khẩn cấp (như OP đặt nó) phát sinh, bạn chỉ cần giải phóng những trang đó trong RAM, bởi vì
Jörg W Mittag

3
Họ đã được trao đổi. Và đó chính xác là lý do tại sao bạn không muốn sử dụng trao đổi "chỉ trong trường hợp khẩn cấp", vì trong trường hợp khẩn cấp, hệ thống đã bị căng thẳng và điều cuối cùng bạn muốn là thêm số lượng lớn I / O vào đó.
Jörg W Mittag

2
Điều khiến nó hoán đổi có thể là quá trình chạy dài: đó là truy cập các tệp trên đĩa. Những tệp trong bộ nhớ sẽ được sử dụng gần đây hơn bộ nhớ của GUI.
jpmc26

3
@ JörgWMittag Bạn có bằng chứng về nhân Linux không, khi mức sử dụng I / O thấp, hãy viết các trang vào vùng trao đổi "chỉ trong trường hợp", tức là không giải phóng chúng khỏi RAM?
jlliagre

10

Có phải quá trình bạn đang chạy một cái gì đó bạn tự tạo ra?

Nếu vậy, có thể đáng để điều chỉnh mã của bạn để mở các tệp bằng O_DIRECTcờ, để trích dẫn trang thủ công -

Cố gắng giảm thiểu hiệu ứng bộ đệm của I / O đến và từ tệp này. Nói chung, điều này sẽ làm giảm hiệu suất, nhưng nó rất hữu ích trong các tình huống đặc biệt, chẳng hạn như khi các ứng dụng thực hiện bộ nhớ đệm của riêng chúng. Tệp I / O được thực hiện trực tiếp đến / từ bộ đệm không gian người dùng. Bản thân cờ O_DIRECT nỗ lực truyền dữ liệu một cách đồng bộ, nhưng không đảm bảo cho cờ O_SYNC rằng dữ liệu và siêu dữ liệu cần thiết được truyền. Để đảm bảo I / O đồng bộ, O_SYNC phải được sử dụng cùng với O_DIRECT. Xem GHI CHÚ dưới đây để thảo luận thêm.


1
Một cách tương tự khác (nhưng có lẽ dễ dàng hơn, vì tôi khá chắc chắn rằng O_DIRECT có các hạn chế căn chỉnh và bạn sẽ giết hiệu suất nếu số lần đọc của bạn không lớn) sẽ được nói với hạt nhân mà bạn sẽ không cần dữ liệu đó nữa, xóa nó khỏi bộ đệm trang. (trên điện thoại hoặc sẽ cung cấp liên kết, xin lỗi)
derobert

1
@derobert Đối với một, nocachelệnh là một hack thuận tiện để làm điều này. (Nó sử dụng LD_PRELOAD để chiếm quyền điều khiển một số cuộc gọi libc).
nguồn

6

Đây là một ý tưởng mà tôi chưa từng thử (và tôi xin lỗi vì hiện tại tôi chưa có thời gian để thử nghiệm điều này).

Giả sử bạn tạo một VM nhỏ chỉ có bộ nhớ 512MB cho quá trình chạy nền của mình, tôi không chắc liệu bạn có muốn điều này có bất kỳ trao đổi, cuộc gọi nào và tắt trao đổi trên hệ thống máy chủ của bạn không.


3

Xóa trao đổi hoặc giảm khoảng 20% ​​( có thể thay đổi theo hệ thống ) vì các hệ điều hành gần đây không sử dụng trao đổi nữa giống như cách họ đã làm trong vài năm trước. Nó có thể trả lời một số câu hỏi của bạn:

-> redhat.com chính thức

một số thông tin của Red Hat bên dưới,

Trước đây, một số nhà cung cấp ứng dụng đã khuyến nghị trao đổi kích thước bằng với RAM, hoặc thậm chí gấp đôi RAM. Bây giờ chúng ta hãy tưởng tượng hệ thống được đề cập ở trên với 2GB RAM và 2GB trao đổi. Một cơ sở dữ liệu trên hệ thống đã bị nhầm cấu hình cho một hệ thống có 5GB RAM. Khi bộ nhớ vật lý được sử dụng hết, trao đổi sẽ được sử dụng. Vì đĩa trao đổi chậm hơn nhiều so với RAM, hiệu suất sẽ giảm và xảy ra sự cố. Tại thời điểm này, thậm chí đăng nhập vào hệ thống có thể trở nên không thể. Khi càng nhiều bộ nhớ được ghi vào, cuối cùng cả bộ nhớ vật lý và trao đổi đều hoàn toàn cạn kiệt và kẻ giết người OOM lao vào, giết chết một hoặc nhiều quá trình. Trong trường hợp của chúng tôi, có khá nhiều trao đổi có sẵn, vì vậy thời gian thực hiện kém là lâu.

https://wiki.debian.org/Swap

một phần của liên kết Debian ở trên,

Thông tin và cân nhắc liên quan đến số lượng trao đổi sẽ sử dụng:

"Lượng không gian hoán đổi được đề nghị theo truyền thống là gấp đôi lượng bộ nhớ hệ thống. Điều này đã thay đổi theo thời gian thành một lần rưỡi bộ nhớ hệ thống, cả hai câu trả lời đều là đường cơ sở đàng hoàng nhưng đang trở thành câu trả lời ít hữu ích hơn cho câu hỏi khi thời gian trôi qua. Có nhiều biến số về hệ thống của bạn và mục đích sử dụng sẽ quyết định việc hoán đổi hệ thống có sẵn mà bạn muốn có. "

Bạn có thể thử:

"Cách tốt nhất để vô hiệu hóa trao đổi trong linux"


Ghi chú cá nhân:


Vì tôi có 6 GB RAM và trong tất cả các hệ điều hành Linux gần đây. Tôi chưa bao giờ thấy bất kỳ dấu hiệu nào của việc sử dụng Hoán đổi. Tôi xác định nó, tôi phải tắt nó để lấy dung lượng (thêm vài gigabyte) và vì đôi khi nó làm chậm hệ thống của tôi.


1
Trước đây, một số nhà cung cấp ứng dụng đã khuyến nghị trao đổi kích thước bằng với RAM, hoặc thậm chí gấp đôi RAM. Tôi cảm thấy già hơn khi thấy điều đó, bằng cách nào đó ... Mặc dù tôi vẫn có một trong số các ổ cứng ở mức rào cản ~ 528 MB và cũng là 2,5 GB, bằng cách nào đó trích dẫn - đó cũng là một thứ gì đó từ rất lâu trước đây ... nó có thể giải thích tại sao tôi thấy những vấn đề tương tự vài năm trước. Tôi tin rằng tôi đã sử dụng sysctl để sửa nó nhưng tôi không nhớ chính xác cài đặt nào nếu đó là đêm trước.
Pryftan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.