Predis: Kesalahan saat membaca baris dari server

Dibuat pada 7 Jun 2011  ·  27Komentar  ·  Sumber: predis/predis

CommunicationException s ditampilkan dengan pesan 'Kesalahan saat membaca baris dari server' dari waktu ke waktu. Bagian Predis dari contoh pelacakan tumpukan:

Message: Error while reading line from the server
Thrown at: /var/www/lib/redis/Predis.php:1568
Trace:
#0 /var/www/lib/redis/Predis.php(1636): Predis\Connection->onCommunicationException('Error while rea...')
#1 /var/www/lib/redis/Predis.php(724): Predis\Connection->readLine()
#2 /var/www/lib/redis/Predis.php(1577): Predis\FastResponseReader->read(Object(Predis\Connection))
#3 /var/www/lib/redis/Predis.php(1586): Predis\Connection->readResponse(Object(Predis\Commands\Auth))
#4 /var/www/lib/redis/Predis.php(225): Predis\Connection->executeCommand(Object(Predis\Commands\Auth))
#5 /var/www/lib/redis/RedisProxy.php(21): Predis\Client->__call('auth', Array)
#6 /var/www/lib/redis/RedisProxy.php(21): Predis\Client->auth('password')

Kami tidak dapat menemukan kesamaan dalam skrip yang terpengaruh. Beberapa kesalahan berasal dari server Redis lokal, beberapa dari yang jauh. Contoh yang terkadang menghasilkan kesalahan ini:

Skrip dijalankan oleh Apache, browser memanggilnya langsung dengan URL, jadi mungkin ada banyak instance yang berjalan sekaligus. Perintah Redis berikut dijalankan melalui Predis (dalam urutan ini; a , b , c dan d adalah tabel yang berbeda):

  • AUTH
  • PILIH
  • ADA
  • (jika suatu kondisi terpenuhi) SETEX
  • PILIH b
  • Rp
  • jika suatu kondisi terpenuhi

    • PILIH b

    • INC

    • PILIH

    • DAPATKAN

    • PILIH

    • Rp

Perintah yang dicetak tebal adalah perintah yang pernah menghasilkan kesalahan. Mayoritas (99%) ada di AUTH.

Lingkungan :

$ redis-server -v
Redis server version 2.2.4 (00000000:0)

Predis version 0.6.6

$ php -v
PHP 5.3.3-0.dotdeb.1 with Suhosin-Patch (cli) (built: Oct  1 2010 08:49:29) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

$ /usr/sbin/apache2ctl -v
Server version: Apache/2.2.9 (Debian)
Server built:   Apr 20 2010 15:40:17

documentation

Semua 27 komentar

Masalah Anda cukup aneh. Pengecualian semacam itu biasanya dilontarkan ketika soket (yang sudah terhubung) mencapai batas waktu selama operasi baca atau tulis, tetapi fakta bahwa Anda melihat kesalahan semacam ini bahkan ketika berhadapan dengan instance lokal Redis membuatnya memang aneh. Apakah Anda menggunakan nilai khusus (dan rendah) untuk parameter read_write_timeout untuk mengonfigurasi koneksi ke Redis?

Tidak, kami tidak melakukannya. Satu-satunya parameter konfigurasi yang diteruskan ke klien adalah connection_timeout dengan nilai 30 (yang lebih tinggi dari default).

Ini mungkin tidak menarik, tetapi saya meretas klien sedikit untuk mencoba membaca lagi saat pengecualian terjadi, dan menambahkan string baca ke teks pengecualian. Saya tidak mengambil terlalu banyak sampel, tetapi string baca tampak seperti beberapa karakter dari keluaran yang valid (tidak benar-benar memverifikasi). Bagaimanapun, itu tidak kosong.

Sunting. Titik data lain: biasanya ada sejumlah besar contoh kesalahan dalam waktu sekitar satu detik, tetapi tidak ada sebelum atau sesudahnya. Saya menyadari ini bisa mengarah pada masalah di Redis; apakah ada cara untuk mengesampingkan Predis sebagai pelakunya (selain menulis ulang panggilan untuk menggunakan bahasa/klien lain)?

Bisakah Anda mencoba untuk membungkus panggilan yang biasanya menghasilkan pengecualian di blok try ... catch dengan kode yang terlihat seperti berikut ini?

<?php
try {
    // Redis commands
}
catch (Predis\CommunicationException $exception) {
    $stream = $exception->getConnection()->getSocket();
    $metadata = var_export(stream_get_meta_data($stream), true);
    // log the $metadata string somewhere so that you can retrieve it
    throw $exception;
}

Dengan $metadata kita harus mendapatkan beberapa detail berguna tentang status aliran PHP yang mendasarinya untuk mulai menebak apa yang terjadi di server Anda saat pengecualian tersebut dilemparkan.

Omong-omong, nilai connection_timeout hanya memiliki efek pada operasi koneksi aliran soket klien ke titik akhir jarak jauh. Sebagai gantinya read_write_timeout digunakan untuk mengatur batas waktu operasi baca dan tulis melalui soket yang terhubung (defaultnya adalah 30 detik jika saya ingat dengan benar). Anda dapat mencoba menetapkan nilai yang lebih tinggi untuk read_write_timeout hanya untuk melihat apakah Anda melihat beberapa perubahan, tetapi lakukan itu hanya setelah mengambil beberapa sampel metadata aliran seperti dijelaskan di atas.

Baiklah, kami akan mencoba keduanya. Pekerjaan dimulai sekitar 12 jam dari sekarang (kita di CET), saya akan melaporkan kembali dengan hasilnya.

Terima kasih.

Maaf, saya baru menyadari bahwa perilaku Predis saat ini tidak sesuai dengan potongan kode tersebut. Anda harus memodifikasi sementara baris kode ini untuk mengembalikan false sehingga sumber aliran yang mendasarinya tidak ditutup sebelum pengecualian diizinkan untuk menyebar.

OK selesai. Belum ada pengecualian.

Mendapat beberapa kesalahan, berikut ini contohnya (semuanya terlihat sama):

Message: Predis socket metadata dump: array (
  'stream_type' => 'tcp_socket/ssl',
  'mode' => 'r+',
  'unread_bytes' => 0,
  'seekable' => false,
  'timed_out' => true,
  'blocked' => true,
  'eof' => false,
)

timed_out => true mengkonfirmasi teori Anda, dan mengumpulkan read_write_timeout akan menyelesaikan masalah, bukan? (atau setidaknya hilangkan dulu)

Menaikkan nilai read_write_timeout _might_ membantu meringankan masalah, tetapi itu benar-benar tergantung pada sumber batas waktu dan nilai defaultnya adalah 60 detik (diverifikasi sekarang) yang sudah merupakan nilai yang sangat tinggi. Selain itu, fakta bahwa skrip Anda dapat terhubung dengan sukses ke Redis menghilangkan masalah yang terkait dengan kelelahan port TCP/IP sementara.

Berapa banyak klien bersamaan yang terhubung ke instans Redis Anda rata-rata? Apakah mungkin bagi Anda untuk menggunakan soket domain UNIX alih-alih TCP/IP untuk terhubung ke instance Redis yang berjalan di locahost dan melihat apakah Anda masih mendapatkan kesalahan acak tersebut?

Pada dua server Redis dengan masalah ada 17 +/- 5 koneksi. Satu memiliki lonjakan maksimal 30, yang lain memiliki lonjakan harian 60-100 (keduanya berlangsung selama beberapa menit, dan tidak cocok dengan waktu kesalahan). Saya akan mencoba menggunakan soket UNIX untuk salah satu server.

Kami mendapat sejumlah kecil kesalahan yang mirip dengan berikut ini:

Message: Connection timed out
Thrown at: /var/www/lib/redis/Predis.php:1568
Trace:
#0 /var/www/lib/redis/Predis.php(1518): Predis\Connection->onCommunicationException('Connection time...', 110)
#1 /var/www/lib/redis/Predis.php(1494): Predis\Connection->redisStreamInitializer(Object(Predis\ConnectionParameters))
#2 /var/www/lib/redis/Predis.php(1648): Predis\Connection->connect()
#3 /var/www/lib/redis/Predis.php(1599): Predis\Connection->getSocket()
#4 /var/www/lib/redis/Predis.php(1573): Predis\Connection->writeBytes('*2??$4??AUTH??$...')
#5 /var/www/lib/redis/Predis.php(1582): Predis\Connection->writeCommand(Object(Predis\Commands\Auth))
#6 /var/www/lib/redis/Predis.php(225): Predis\Connection->executeCommand(Object(Predis\Commands\Auth))
#7 /var/www/lib/redis/RedisProxy.php(21): Predis\Client->__call('auth', Array)

Ini bisa jadi hanya karena perubahan ini , tetapi mungkin ada beberapa info tambahan untuk Anda.

Yah, melihat bahwa Anda mendapatkan waktu tunggu juga selama operasi connect() agak meyakinkan, itu akan benar-benar aneh jika tidak :-) Bagaimanapun, 100 koneksi simultan ke Redis seharusnya tidak menimbulkan masalah (setidaknya di sisi Redis).

Omong-omong, saya baru menyadari bahwa Anda menjalankan PHP dengan Xdebug dimuat. Selain fakta bahwa Xdebug dapat memperlambat kode PHP Anda sedikit untuk lingkungan produksi, saya tidak tahu apakah itu bisa mengacaukan aliran PHP atau sesuatu yang sedang dimuat. Anda harus mencoba untuk menonaktifkannya, jika mungkin, dan bahkan jika melakukan ini tidak menyelesaikan masalah... yah, saya kehilangan kata-kata.

Dari bagaimana keadaan berubah, ini sepertinya bukan bug Predis, dan satu-satunya hal yang tersisa yang dapat saya pikirkan adalah:

  • masalah konektivitas (tetapi ini tidak masuk akal untuk koneksi di localhost)
  • semacam kesalahan konfigurasi lingkungan PHP + Apache (Saya tidak menggunakan Apache sejak bertahun-tahun, jadi saya tidak dapat membantu)

Baiklah, jika menonaktifkan Xdebug tidak menyelesaikan masalah, maka saya akan mencoba mereproduksi ini dengan pustaka klien lain. Mudah-mudahan itu akan mempersempit segalanya bagi orang-orang Redis untuk mengetahuinya. Kami akan menggunakan soket unix untuk koneksi loopback, bahkan jika soket tersebut tidak menyelesaikan masalah ini (percepatan baik untuk kesehatan), jadi terima kasih untuk penunjuk itu juga.

Terima kasih atas waktu Anda :)

Beri tahu saya bagaimana keadaannya, sekarang saya penasaran :-)

Tentu, saya akan menulis di sini dengan hasilnya. Tidak ada kesalahan sejak saya menonaktifkan Xdebug, saya harap akan tetap seperti itu.

Hanya menambahkan tautan ke diskusi yang sedang berlangsung tentang masalah ini (batas waktu) dari milis Redis karena memiliki beberapa tips menarik.

Sebenarnya, saya menulis OP dari utas itu :) Masih sangat baik bagi Anda untuk memposting tautannya.

Penyebab masalah ini adalah driver Realtek yang salah (r8169 sebelum kernel 2.6.30 bermasalah, harus menggunakan r8168). Tidak ada hubungannya dengan Redis atau Predis.

Terima kasih atas pembaruannya, ini mungkin menjadi informasi berharga bagi orang lain. Men-debug masalah aneh semacam ini bisa jadi sulit dan memakan waktu ketika penyebabnya ada di suatu tempat di tingkat yang lebih rendah.

Abesto, maaf mengganggu - tetapi kami mengalami masalah yang sama, saya bertanya-tanya bagaimana Anda mengetahui bahwa "Penyebab masalah ini adalah driver Realtek yang salah" ??

Terima kasih!

@ rookie7799 Tidak ada masalah sama sekali. /var/log/kernel.log berisi pesan "antarmuka" pada saat yang sama saat kesalahan terjadi; tautan tidak aktif selama beberapa waktu sebelum pesan-pesan ini.

Sebutkan masalah dan solusi terperinci di Hetzner: http://wiki.hetzner.de/index.php/Installation_des_r8168-Treibers/en

Maaf untuk mengambil begitu lama untuk menjawab.

Saya mendapat masalah yang sama ketika saya menggunakan perintah "brpop bar 0" dalam kode. pengaturan read_write_timeout ke -1 dapat menyelesaikannya tetapi ... apakah ada solusi yang lebih baik? atau dapatkah solusi ini menyebabkan masalah lain yang tidak diketahui? ngomong-ngomong, untuk sistem kami, batas waktu 60-an tidak cukup :(

Anda bisa melakukan operasi pemblokiran dengan argumen kedua bukan nol. Ini melepaskan blok setelah "batas waktu" tercapai. Anda kemudian dapat menjalankan beberapa pemeriksaan, dan mengeluarkan perintah pemblokiran lagi. Dengan cara ini Anda juga menghindari keharusan mengonfigurasi server agar koneksi tidak terputus terlalu lama.

Itu ide yang bagus, terima kasih atas jawabannya :)

Maaf untuk mengungkit ini lagi setelah sekian lama, tapi saya pikir saya punya alasan berbeda mengapa saya mendapatkan pesan kesalahan ini. Saya mencoba men-debug aliran seperti yang disebutkan sebelumnya dan mendapatkan ini:

array(7) {
  ["stream_type"]=>
  string(14) "tcp_socket/ssl"
  ["mode"]=>
  string(2) "r+"
  ["unread_bytes"]=>
  int(0)
  ["seekable"]=>
  bool(false)
  ["timed_out"]=>
  bool(false)
  ["blocked"]=>
  bool(true)
  ["eof"]=>
  bool(false)
}

read_write_timeout diset ke -1 , dan kita menggunakan satu master dan satu slave dengan replication => true . Dilihat dari alamat IP, kesalahan dipicu pada master.

Adakah ide tentang memblokir koneksi mode? Saya melihat perpustakaan PHP Redis lainnya memiliki ini dapat dikonfigurasi.

Kami baru saja beralih dari phpredis dan ini adalah pekerjaan cron, kesalahan terjadi tepat setelah 60 detik.

Terima kasih!

Ini adalah bagaimana saya berhasil menangkap info debug:

          catch (Predis\CommunicationException $exception) {
                $stream = $exception->getConnection()->getResource();
                $errorMessage = var_export(stream_get_meta_data($stream), true);
                //Log::info($errorMessage);
                continue;
            }

Saya mendapatkan yang berikut ini:

array (
  'timed_out' => false,
  'blocked' => true,
  'eof' => false,
  'stream_type' => 'tcp_socket/ssl',
  'mode' => 'r+',
  'unread_bytes' => 0,
  'seekable' => false,
)

Saya telah menetapkan read_write_timeout ke -1, timeout di redis.conf ke 0, param kedua ke blpop sebagai 0. Adakah yang berhasil mengetahui lebih lanjut tentang ini?

Info lebih lanjut:
Menggunakan redis 3 (gambar buruh pelabuhan, varian alpine) dengan Laravel 5.1 dalam perintah artisan yang berjalan lama.

Tidak Ben, saya belum bisa menyelesaikan ini.

Ben Cromwell menulis:
>

Hai @pravindahal https://github.com/pravindahal

Terima kasih telah memposting kode penangkap debug. Apakah Anda mendapatkan di mana saja?
menuju resolusi?

Saya memiliki masalah serupa

| susunan (
'stream_type' => 'tcp_socket/ssl',
'modus' => 'r+',
'unread_bytes' => 0,
'dapat dicari' => salah,
'timed_out' => salah,
'diblokir' => benar,
'eof' => salah,
)
|


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/nrk/predis/issues/32#issuecomment-263821705 , atau
matikan utasnya
https://github.com/notifications/unsubscribe-auth/AA2nC7YRPNChZdEOx9c1N3pBJNbr0KW3ks5rDT5XgaJpZM4HN5ze .

Maaf, saya menghapus komentar saya karena saya tidak yakin masalahnya sama
setelah lebih banyak debug.

Mungkin saja.

Saya menukar Predis untuk phpredis dan mengalami kesalahan yang sama. Setelah
pencarian lebih lanjut saya menemukan pengaturan default_socket_timeout dan mengaturnya ke
-1. Ini ada di php.ini

http://php.net/manual/en/filesystem.configuration.php#ini.default -socket-timeout

Itu berhasil. Sepertinya itu perlu meskipun mengatur
parameter koneksi read_write_timeout. Pengaturan PHP mengalahkannya, keduanya
dibutuhkan oleh penampilan.

Pada 30 November 2016 pukul 11:43, Pravin Dahal [email protected] menulis:

Tidak Ben, saya belum bisa menyelesaikan ini.

Ben Cromwell menulis:
>

Hai @pravindahal https://github.com/pravindahal

Terima kasih telah memposting kode penangkap debug. Apakah Anda mendapatkan di mana saja?
menuju resolusi?

Saya memiliki masalah serupa

| susunan (
'stream_type' => 'tcp_socket/ssl',
'modus' => 'r+',
'unread_bytes' => 0,
'dapat dicari' => salah,
'timed_out' => salah,
'diblokir' => benar,
'eof' => salah,
)
|


Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/nrk/predis/issues/32#issuecomment-263821705 , atau
matikan utasnya
AA2nC7YRPNChZdEOx9c1N3pBJNbr0KW3ks5rDT5XgaJpZM4HN5ze>.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/nrk/predis/issues/32#issuecomment-263853786 , atau bisu
benang
https://github.com/notifications/unsubscribe-auth/AApvTxieAw1-Jfa6NvXJbwKTW8VP9rgfks5rDWFYgaJpZM4HN5ze
.

Saya menemukan diri saya kembali ke sini hampir setahun kemudian dan merasa terdorong untuk berkomentar.

Komposer tidak berfungsi (instal/perbarui paket) dengan pengaturan soket yang diubah.

Tidak tahu mengapa paket tersebut tampaknya tidak menghormati pengaturan konfigurasi dan tidak dapat mengesampingkan default PHP. Meninggalkan komentar ini di sini kalau-kalau ada yang membaca ini dan tahu solusinya!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat