Rumah  >  Artikel  >  pangkalan data  >  Apakah perbezaan antara redis dan Memcached?

Apakah perbezaan antara redis dan Memcached?

王林
王林ke hadapan
2023-06-03 09:14:041326semak imbas

redis ialah pangkalan data, tetapi tidak seperti pangkalan data tradisional, data redis disimpan dalam ingatan, jadi kelajuan baca dan tulis sangat pantas, jadi redis digunakan secara meluas dalam arah cache. memcached ialah pelayan cache memori teragih berprestasi tinggi. Tujuan umum penggunaan adalah untuk meningkatkan kelajuan dan kebolehskalaan aplikasi web dinamik dengan menyimpan cache hasil pertanyaan pangkalan data dan mengurangkan bilangan akses pangkalan data.

Apakah perbezaan antara redis dan Memcached?

Perbandingan berwibawa

Salvatore Sanfilippo, pengarang Redis, pernah membandingkan dua sistem storan data berasaskan memori ini:

  1. Redis menyokong operasi data sebelah pelayan: Berbanding dengan Memcached, Redis mempunyai lebih banyak struktur data dan menyokong operasi data yang lebih kaya Biasanya dalam Memcached, anda perlu mendapatkan data kepada klien untuk operasi serupa Buat pengubahsuaian dan kemudian tetapkannya. belakang. Ini meningkatkan bilangan IO rangkaian dan volum data. Berbanding dengan GET/SET umum, operasi kompleks ini biasanya sama cekap dalam Redis. Oleh itu, jika anda memerlukan cache untuk menyokong struktur dan operasi yang lebih kompleks, maka Redis akan menjadi pilihan yang baik.

  2. Perbandingan kecekapan penggunaan memori: Memcached mempunyai penggunaan memori yang lebih tinggi jika storan nilai kunci mudah digunakan, dan jika Redis menggunakan struktur cincang untuk storan nilai kunci, disebabkan gabungannya Dengan ini jenis pemampatan, penggunaan memorinya akan lebih tinggi daripada Memcached.

  3. Perbandingan prestasi: Memandangkan Redis hanya menggunakan satu teras, manakala Memcached boleh menggunakan berbilang teras, secara purata, Redis mempunyai prestasi yang lebih tinggi daripada Memcached apabila menyimpan data kecil pada setiap teras. Untuk data lebih daripada 100k, prestasi Memcached lebih tinggi daripada Redis Walaupun Redis baru-baru ini telah dioptimumkan untuk prestasi menyimpan data besar, ia masih lebih rendah sedikit daripada Memcached.

Secara khusus mengapa kesimpulan di atas muncul, berikut adalah maklumat yang dikumpul:

1 Jenis data yang berbeza disokong

dan Memcached hanya menyokong mudah yang Rekod data struktur nilai kunci adalah berbeza, dan jenis data yang disokong oleh Redis adalah lebih kaya. Jenis data yang paling biasa termasuk String, Hash, Senarai, Set dan Set Isih. Redis menggunakan objek redisObject untuk mewakili semua kunci dan nilai. Maklumat utama redisObject ditunjukkan dalam rajah:

jenis mewakili jenis data tertentu bagi objek nilai, dan pengekodan ialah cara jenis data yang berbeza disimpan di dalam redis Contohnya: type=string mewakili nilai disimpan Rentetan biasa, maka pengekodan yang sepadan boleh menjadi mentah atau int Jika ia adalah int, ia bermakna redis sebenar menyimpan dan mewakili rentetan mengikut kelas berangka Sudah tentu, rentetan itu sendiri boleh diwakili oleh nilai berangka, seperti :"123″ "456". Hanya apabila fungsi memori maya Redis dihidupkan, medan vm sebenarnya akan memperuntukkan memori. Fungsi ini dimatikan secara lalai.

1) Rentetan

Arahan biasa: set/get/decr/incr/mget, dsb.;

Senario aplikasi: String ialah jenis data yang paling biasa digunakan dan biasa storan kunci/nilai adalah Boleh diklasifikasikan ke dalam kategori ini;

Kaedah pelaksanaan: Rentetan disimpan secara dalaman dalam redis sebagai rentetan secara lalai, yang dirujuk oleh redisObject Apabila menghadapi incr, decr dan operasi lain, ia akan ditukar kepada jenis berangka untuk pengiraan. Pada masa ini medan pengekodan redisObject ialah int. 2) Hash

Arahan biasa: hget/hset/hgetall, dsb. senario: Kami ingin menyimpan data objek maklumat pengguna, termasuk ID pengguna, nama pengguna, umur dan hari lahir Melalui ID pengguna, kami berharap untuk mendapatkan nama pengguna, umur atau hari lahirnya; Hash sebenarnya adalah Nilai yang disimpan secara dalaman Ia adalah HashMap dan menyediakan antara muka untuk mengakses secara langsung ahli Peta ini Seperti yang ditunjukkan dalam rajah, kuncinya ialah ID pengguna dan nilainya ialah Peta ini nama atribut ahli, dan nilainya ialah nilai atribut Pengubahsuaian dan akses boleh dilakukan secara langsung melalui kunci Peta dalamannya (kunci Peta dalaman dipanggil medan dalam Redis), iaitu, data atribut yang sepadan boleh. dimanipulasi melalui kekunci (ID pengguna) + medan (label atribut) Pelaksanaan semasa HashMap Terdapat dua cara: apabila terdapat sedikit ahli HashMap, Redis akan menggunakan kaedah seperti tatasusunan satu dimensi untuk menyimpannya secara padat. untuk menjimatkan memori, bukannya menggunakan struktur HashMap sebenar Pada masa ini, pengekodan redisObject nilai yang sepadan adalah zipmap Apabila bilangannya bertambah, ia akan ditukar secara automatik menjadi HashMap sebenar pengekodan adalah ht pada masa ini. 3) Senaraikan

Arahan biasa: lpush/rpush/lpop/rpop/, dsb.

Senario aplikasi: Terdapat banyak senario aplikasi. untuk senarai Redis, dan ia juga merupakan salah satu struktur data yang paling penting bagi Redis Contohnya, senarai ikuti twitter, senarai peminat, dll. semuanya boleh dilaksanakan menggunakan struktur senarai Redis; pelaksanaan senarai Redis ialah senarai terpaut dua hala, yang boleh menyokong carian terbalik dan traversal, yang lebih mudah untuk dikendalikan, tetapi ia membawa beberapa overhed memori tambahan dalam Redis, termasuk menghantar baris gilir penimbal Struktur data ini juga digunakan .

4) Tetapkan

Arahan biasa: sadd/spop/smembers/sunion, dsb.;

Senario aplikasi: Fungsi luaran yang disediakan oleh set Redis adalah serupa dengan fungsi senarai Perkara yang istimewa ialah set itu boleh menyahgandakan secara automatik Apabila anda perlu menyimpan data senarai dan tidak mahu data pendua muncul, tetapkan Ia ialah pilihan yang baik, dan set menyediakan antara muka penting untuk menentukan sama ada ahli berada dalam koleksi set, senarai yang tidak dapat menyediakan

Kaedah pelaksanaan: Pelaksanaan dalaman set ialah nilai selama-lamanya HashMap nol sebenarnya; diselesaikan dengan cepat dengan mengira cincang Inilah sebabnya set boleh menyediakan cara untuk menentukan sama ada ahli berada dalam set.

5) Set Diisih

Arahan biasa: zadd/zrange/zrem/zcard, dsb.

Senario aplikasi: Senario penggunaan set diisih semula dan Set adalah serupa, perbezaannya ialah set itu tidak dipesan secara automatik, manakala set diisih boleh mengisih ahli dengan menyediakan parameter keutamaan (skor) tambahan oleh pengguna, dan sisipan diarahkan, iaitu, diisih secara automatik. Apabila anda memerlukan senarai set tersusun dan bukan pendua, anda boleh memilih struktur data set diisih Contohnya, garis masa awam Twitter boleh disimpan dengan masa penerbitan sebagai skor, supaya ia akan diisih secara automatik mengikut masa apabila diambil.

Kaedah pelaksanaan: Set isih Redis secara dalaman menggunakan HashMap dan senarai langkau (SkipList) untuk memastikan penyimpanan dan susunan data HashMap menyimpan pemetaan daripada ahli kepada markah, manakala senarai langkau menyimpan semua Ahli disusun berdasarkan. pada skor yang disimpan dalam HashMap Menggunakan struktur jadual lompat boleh mencapai kecekapan carian yang lebih tinggi dan agak mudah untuk dilaksanakan.

2. Mekanisme pengurusan memori yang berbeza

Dalam Redis, tidak semua data sentiasa disimpan dalam ingatan. Ini adalah perbezaan terbesar berbanding dengan Memcached. Apabila memori fizikal kehabisan, Redis boleh menukar beberapa nilai yang tidak digunakan untuk masa yang lama ke cakera. Redis hanya akan menyimpan semua maklumat utama Jika Redis mendapati bahawa penggunaan memori melebihi ambang tertentu, operasi swap akan dicetuskan Redis mengira kekunci yang sepadan dengan nilai yang diperlukan berdasarkan "swappability = age*log(size_in_memory)" swap ke. cakera. Kemudian nilai yang sepadan dengan kunci ini dikekalkan ke cakera dan dikosongkan dalam ingatan. Ciri ini membolehkan Redis mengekalkan data yang melebihi saiz memori mesinnya sendiri. Sudah tentu, kapasiti memori mesin mesti mencukupi untuk menyimpan semua data utama, kerana data ini tidak akan ditukar. Pada masa yang sama, apabila Redis menukar data dalam memori ke cakera, benang utama yang menyediakan perkhidmatan dan sub-benang yang melakukan operasi swap akan berkongsi bahagian memori ini, jadi jika data yang perlu swapped dikemas kini, Redis akan menyekat operasi sehingga sub-thread Pengubahsuaian hanya boleh dibuat selepas menyelesaikan operasi swap. Apabila membaca data daripada Redis, jika nilai yang sepadan dengan kunci baca tiada dalam memori, maka Redis perlu memuatkan data yang sepadan daripada fail swap dan kemudian mengembalikannya kepada peminta. Terdapat masalah kumpulan benang I/O di sini. Secara lalai, Redis akan menyekat, iaitu, ia tidak akan bertindak balas sehingga semua fail swap dimuatkan. Strategi ini lebih sesuai apabila bilangan pelanggan adalah kecil dan operasi kelompok dilakukan. Jika anda ingin menggunakan Redis dalam aplikasi laman web berskala besar dengan konkurensi yang tinggi, ia jelas tidak mencukupi untuk memenuhi keperluan. Oleh itu, apabila menjalankan Redis, kami menetapkan saiz kumpulan benang I/O dan melakukan operasi serentak pada permintaan baca yang perlu memuatkan data yang sepadan daripada fail swap untuk mengurangkan masa penyekatan.

Untuk sistem pangkalan data berasaskan memori seperti Redis dan Memcached, kecekapan pengurusan memori adalah faktor utama yang mempengaruhi prestasi sistem. Fungsi malloc/free dalam bahasa C tradisional ialah kaedah yang paling biasa digunakan untuk memperuntukkan dan melepaskan memori, tetapi kaedah ini mempunyai kelemahan utama: pertama, untuk pembangun, malloc yang tidak sepadan dan percuma boleh menyebabkan kebocoran memori kedua, Panggilan yang kerap akan menyebabkan sejumlah besar serpihan memori yang tidak boleh dikitar semula dan digunakan semula, mengurangkan penggunaan memori akhirnya, sebagai panggilan sistem, overhed sistemnya jauh lebih besar daripada panggilan fungsi biasa. Oleh itu, untuk meningkatkan kecekapan pengurusan memori, penyelesaian pengurusan memori yang cekap tidak akan menggunakan panggilan malloc/percuma secara langsung. Kedua-dua Redis dan Memcached menggunakan mekanisme pengurusan memori mereka sendiri, tetapi kaedah pelaksanaannya sangat berbeza Mekanisme pengurusan memori kedua-duanya akan diperkenalkan secara berasingan di bawah.

Memcached menggunakan mekanisme Peruntukan Slab secara lalai untuk mengurus memori Idea utama adalah untuk membahagikan memori yang diperuntukkan kepada blok dengan panjang tertentu mengikut saiz yang telah ditetapkan untuk menyimpan rekod data nilai kunci dengan panjang yang sepadan untuk menyelesaikan sepenuhnya pemecahan memori. masalah. Mekanisme Peruntukan Papak hanya direka untuk menyimpan data luaran, yang bermaksud bahawa semua data nilai kunci disimpan dalam sistem Peruntukan Papak, manakala permintaan memori lain untuk Memcached digunakan melalui malloc/percuma biasa, kerana bilangan permintaan ini dan Kekerapan menentukan bahawa ia tidak akan menjejaskan prestasi keseluruhan sistem Prinsip Peruntukan Slab agak mudah. Seperti yang ditunjukkan dalam rajah, ia pertama kali digunakan untuk blok memori yang besar daripada sistem pengendalian, membahagikannya kepada ketulan pelbagai saiz, dan membahagikan ketulan yang sama saiz kepada kumpulan kelas papak. Chunk digunakan sebagai unit terkecil untuk menyimpan data nilai kunci. Saiz setiap Kelas Papak boleh dikawal dengan menentukan Faktor Pertumbuhan apabila Memcached dimulakan. Andaikan nilai Growth Factor dalam rajah ialah 1.25 Jika saiz kumpulan pertama Chunks ialah 88 bait, saiz kumpulan kedua Chunks ialah 112 bait, dan seterusnya.

Apabila Memcached menerima data yang dihantar oleh pelanggan, ia akan mula-mula memilih Kelas Papak yang paling sesuai berdasarkan saiz data yang diterima, dan kemudian menanyakan senarai bahagian percuma dalam Kelas Papak yang disimpan oleh Memcached. Cari Chunk yang boleh digunakan untuk menyimpan data. Apabila pangkalan data tamat tempoh atau dibuang, Chunk yang terletak di dalamnya boleh dikitar semula dan ditambah semula ke senarai percuma.

Daripada proses di atas, kita dapat melihat bahawa sistem pengurusan memori Memcached sangat cekap dan tidak akan menyebabkan pemecahan memori, tetapi kelemahan terbesarnya ialah ia membawa kepada pembaziran ruang. Data panjang boleh ubah tidak boleh menggunakan sepenuhnya panjang khusus ruang memori yang diperuntukkan untuk setiap Chunk. Seperti yang ditunjukkan dalam rajah, 100 bait data dicache ke dalam Bongkah 128 bait, dan baki 28 bait dibazirkan.

Cara Redis melaksanakan pengurusan memori terutamanya melibatkan dua fail zmalloc.h dan zmalloc.c dalam kod sumber. Bagi memudahkan pengurusan memori, Redis akan menyimpan saiz memori ini di kepala blok memori selepas memperuntukkan sekeping memori. real_ptr menunjuk ke blok memori yang dikembalikan selepas redis memanggil malloc. Redis menyimpan saiz saiz blok memori dalam pengepala Saiz memori yang diduduki oleh saiz diketahui dan merupakan panjang jenis size_t, dan kemudian mengembalikan ret_ptr. Apabila memori perlu dikeluarkan, ret_ptr dihantar kepada pengurus memori. Melalui ret_ptr, program boleh mengira nilai real_ptr dengan mudah, dan kemudian menghantar real_ptr untuk membebaskan memori.

Redis merekodkan semua peruntukan memori dengan mentakrifkan tatasusunan ini ialah ZMALLOC_MAX_ALLOC_STAT. Setiap nombor mewakili bilangan blok memori yang diperuntukkan pada masa ini oleh program, dan saiz setiap blok memori adalah sama dengan indeks tatasusunan di mana ia berada. Dalam kod sumber, tatasusunan ini ialah zmalloc_allocations. zmalloc_allocations[16] mewakili bilangan blok memori yang diperuntukkan dengan panjang 16 bait. Terdapat pembolehubah statik used_memory dalam zmalloc.c untuk merekodkan jumlah saiz memori yang diperuntukkan pada masa ini. Oleh itu, secara amnya, Redis menggunakan mallc/percuma berpakej, yang jauh lebih mudah daripada kaedah pengurusan memori Memcached.

3. Sokongan kegigihan data

Walaupun Redis ialah sistem storan berasaskan memori, ia sendiri menyokong kegigihan data memori dan menyediakan dua strategi kegigihan utama: Snapshot RDB dan log AOF. Memcached tidak menyokong operasi kegigihan data.

1) petikan RDB

Petikan RDB ialah mekanisme kegigihan Redis, yang membolehkan pengguna menyimpan petikan data semasa sebagai fail data. Redis menggunakan mekanisme salinan atas perintah fork untuk menjana syot kilat yang ditulis secara berterusan ke pangkalan data. Apabila menjana syot kilat, gunakan operasi garpu untuk mencipta proses kanak-kanak dan gelung semua data dalam proses kanak-kanak dan tuliskannya pada fail RDB. Kita boleh mengkonfigurasi masa penjanaan syot kilat RDB melalui perintah simpan Redis Contohnya, kita boleh mengkonfigurasi syot kilat untuk dijana selepas 10 minit, atau syot kilat selepas 1,000 tulisan, atau berbilang peraturan boleh dilaksanakan bersama. Takrif peraturan ini adalah dalam fail konfigurasi Redis Anda juga boleh menetapkan peraturan semasa Redis berjalan melalui arahan SET CONFIG Redis tanpa memulakan semula Redis.

Fail RDB Redis tidak akan rosak kerana operasi penulisannya dilakukan dalam proses baharu Apabila fail RDB baharu dijana, proses anak yang dihasilkan oleh Redis akan menulis data ke fail sementara dahulu. menamakan semula fail sementara kepada fail RDB melalui panggilan sistem nama semula atom, supaya jika kegagalan berlaku pada bila-bila masa, fail Redis RDB sentiasa tersedia. Dalam pelaksanaan dalaman penyegerakan tuan-hamba Redis, fail RDB juga memainkan peranan penting. RDB mempunyai kekurangannya, iaitu, apabila terdapat masalah dengan pangkalan data, data yang disimpan dalam fail RDB kami bukanlah baharu Semua data daripada penjanaan fail RDB yang terakhir hingga penutupan Redis akan hilang. Dalam sesetengah perniagaan, ini boleh diterima.

2) Log AOF

Nama penuh log AOF ialah "Tambah Tulis Fail", iaitu fail log yang dilampirkan dan ditulis secara berterusan. Berbeza daripada binlog pangkalan data umum, fail AOF ialah teks biasa yang boleh dikenal pasti, dan kandungannya ialah arahan standard Redis satu demi satu. Hanya arahan yang akan menyebabkan data diubah suai akan dilampirkan pada fail AOF. Setiap arahan untuk mengubah suai data menghasilkan log, dan fail AOF akan menjadi lebih besar dan lebih besar, jadi Redis menyediakan satu lagi fungsi yang dipanggil penulisan semula AOF. Fungsinya adalah untuk menjana semula fail AOF Hanya akan ada satu operasi pada rekod dalam fail AOF baharu, tidak seperti fail lama, yang mungkin merekodkan berbilang operasi pada nilai yang sama. AOF dijana dengan cara yang serupa dengan RDB, dengan memotong proses, melintasi data secara terus dan menulisnya ke fail AOF sementara yang baharu. Semasa data sedang ditulis ke fail baharu, semua log operasi tulis masih akan direkodkan dalam fail AOF asal dan akan direkodkan dalam penimbal memori pada masa yang sama. Selepas menyelesaikan operasi penting, semua log penimbal akan ditulis ke fail sementara dalam kelompok. Seterusnya, gunakan perintah "rename" atom untuk menggantikan fail AOF lama dengan fail AOF baharu.

AOF ialah operasi menulis fail Tujuannya adalah untuk menulis log operasi ke cakera, jadi ia juga akan menghadapi proses operasi menulis yang kami nyatakan di atas. Selepas memanggil tulis pada AOF dalam Redis, gunakan pilihan appendfsync untuk mengawal masa yang diperlukan untuk memanggil fsync untuk menulisnya ke cakera Kekuatan keselamatan tiga tetapan appendfsync di bawah menjadi lebih kuat.

  • appendfsync no Apabila appendfsync ditetapkan kepada tidak, Redis tidak akan memanggil fsync secara aktif untuk menyegerakkan kandungan log AOF ke cakera, jadi semua ini bergantung sepenuhnya pada penyahpepijatan sistem pengendalian. Dalam kebanyakan sistem pengendalian Linux, operasi fsync dilakukan setiap 30 saat untuk menulis data penimbal ke cakera.

  • appendfsync everysec Apabila appendfsync ditetapkan kepada everysec, Redis akan membuat panggilan fsync setiap saat secara lalai untuk menulis data dalam penimbal ke cakera. Tetapi apabila panggilan fsync ini bertahan lebih lama daripada 1 saat. Redis akan menggunakan strategi menangguhkan fsync dan menunggu satu saat lagi. Maksudnya, fsync akan dilakukan selepas dua saat. Kali ini fsync akan dilakukan tidak kira berapa lama masa yang diperlukan untuk dilaksanakan. Operasi tulis semasa akan disekat kerana deskriptor fail akan disekat semasa operasi fsync sedang dijalankan. Oleh itu, dalam keadaan biasa, Redis akan melakukan operasi fsync setiap saat. Dalam kes yang paling teruk, operasi fsync berlaku setiap dua saat. Operasi ini dipanggil komit kumpulan dalam kebanyakan sistem pangkalan data Ia menggabungkan data berbilang operasi tulis dan menulis log ke cakera sekaligus.

  • appednfsync sentiasa Apabila appendfsync ditetapkan kepada sentiasa, fsync akan dipanggil sekali untuk setiap operasi tulis Pada masa ini, data adalah yang paling selamat, kerana fsync akan dilaksanakan setiap masa, prestasinya juga akan terjejas.

Untuk keperluan perniagaan am, adalah disyorkan untuk menggunakan RDB untuk kegigihan Sebabnya ialah overhed RDB jauh lebih rendah daripada log AOF loss , adalah disyorkan untuk menggunakan log AOF.

4. Perbezaan dalam pengurusan kluster

Memcached ialah sistem penimbalan data memori penuh Walaupun Redis menyokong kegigihan data, memori penuh adalah intipati prestasi tingginya. Sebagai sistem storan berasaskan memori, saiz memori fizikal mesin ialah jumlah maksimum data yang boleh ditampung oleh sistem. Untuk mengembangkan keupayaan storan, apabila jumlah data yang akan diproses melebihi had memori fizikal mesin tunggal, kelompok teragih perlu diwujudkan.

Memcached sendiri tidak menyokong pengedaran, jadi storan teragih Memcached hanya boleh dilaksanakan pada klien melalui algoritma yang diedarkan seperti pencincangan yang konsisten. Rajah di bawah menunjukkan seni bina pelaksanaan storan teragih Memcached. Sebelum pelanggan menghantar data ke kluster Memcached, nod sasaran data akan dikira terlebih dahulu melalui algoritma teragih terbina dalam, dan kemudian data akan dihantar terus ke nod untuk penyimpanan. Apabila pelanggan menanyakan data, ia mesti terlebih dahulu mengira nod di mana data yang hendak disoal terletak, dan kemudian menghantar permintaan pertanyaan kepada nod untuk mendapatkan data.

Berbanding dengan Memcached, yang hanya boleh menggunakan klien untuk melaksanakan storan teragih, Redis lebih suka membina storan teragih di bahagian pelayan. Versi terkini Redis sudah pun menyokong fungsi storan teragih. Kluster Redis ialah versi lanjutan Redis yang melaksanakan pengedaran dan membenarkan titik kegagalan tunggal Ia tidak mempunyai nod pusat dan mempunyai skalabiliti linear. Rajah di bawah menunjukkan seni bina storan teragih Kluster Redis, di mana nod berkomunikasi antara satu sama lain melalui protokol binari, dan antara nod dan pelanggan berkomunikasi melalui protokol ascii. Dari segi strategi peletakan data, Redis Cluster membahagikan keseluruhan medan nilai kunci kepada 4096 slot cincang, dan setiap nod boleh menyimpan satu atau lebih slot cincang Maksudnya, bilangan maksimum nod yang disokong oleh Redis Cluster ialah 4096. Algoritma teragih yang digunakan oleh Redis Cluster juga sangat mudah: crc16(key) % HASH_SLOTS_NUMBER.

Redis Cluster memperkenalkan Master nod dan Slave nod untuk memastikan data masih tersedia sekiranya berlaku satu titik kegagalan. Dalam Kluster Redis, setiap nod Induk mempunyai dua nod Hamba yang sepadan untuk redundansi. Dengan cara ini, dalam keseluruhan kluster, masa henti mana-mana dua nod tidak akan menyebabkan data tidak tersedia. Setelah nod Induk di luar talian, kluster secara automatik memilih nod Induk baharu daripada nod Hamba.

Atas ialah kandungan terperinci Apakah perbezaan antara redis dan Memcached?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam