kuyruk erişim eşzamanlılık çözümleri nelerdir?

4 Cevap php

Ben bir kuyruk sisteminin uygulanması zorluk bulmaya çalışıyorum. Ben temel bir kuyruk uygulamak için biliyorum, bu yüzden ben biraz arka plan ile sonra ben ne hakkında biraz anlatacağım:

Ben mesajları alınacaktır bir kuyruk uygulanması olacak, bu birkaç kullanıcılardan gelecek, mesajlar (birden oluşumları bir UI perspektiften i kısıtlayan olacak Tutanakları hassasiyetle izin kullanıcı tanımlı zamanlarda yayınlanmıştır planlanıyor olacak : sistemi gibi "her dakika veya her saatte bir" tekrarlar ama id yine bu idare edebilmek için).

Here is where my question comes in: Eventually I may be in a situation (and maybe not) where MANY messages need to be posted at the current time, I'd like to have several processes (multiple instances of a script) running to fetch [x,10,25] number of messages from the queue at a time and process them. The problem is: how to do this so that each instance processes unique messages (without processing something that is already being processed by another instance)? I'm worried about current connections, how to lock records, and anything else i may not be thinking about.

Ben kullanarak olacak Teknolojileri PHP ve MySQL vardır. Ben benim arama, gerçek dünya örnekleri, düşünceler, yorumlar ve fikirleri kullanarak gerektiğini yukarıda koşulları bazı çözümler arıyorum?

Hepinize teşekkür!

Bir çözüm i Amazon Basit Kuyruk Servisi'ni kullanarak genelinde edildi geldi ... o eşsiz mesaj işleme / kilitleme http://aws.amazon.com/sqs/ vaat

4 Cevap

Peki, ben böyle yapardım:

Mesajları için tablo yapın ve iki daha fazla alan eklemek - "Process_ID" ve "PROCESS_TIME". Bu daha sonra açıklanacaktır.

Her sürecini benzersiz bir kimliği verin. (O zaman daha kolay ayırt edebilirsiniz) Onlar (bir GUID gibi) başlangıçta bunu üretebilir, ya da bunları kendiniz atayabilirsiniz.

Bir süreç bir sürü mesaj almak istediği zaman, o zaman böyle bir şey yapar:

  1. UPDATE messages SET process_id=$id, process_time=now() where process_id is null LIMIT 20
  2. SEÇİN * mesajlar WHERE Process_ID = $ id

Bu 20 "özgür" iletileri bulmak ve onları "kilit" olacak. Sonra kilitli iletileri bulmak ve bunları işleyecek. Her mesaj işlendikten sonra, DELETE bunu.

UPDATE deyimi otomatik bir işlemin her tür ifadeyi sarar InnoDB, kullanmak, özellikle, oldukça atomik olmalıdır. MySQL orada tüm eşzamanlılık özen.

PROCESS_TIME alan isteğe bağlıdır, ancak bir süreç astı zaman görmek için kullanabilirsiniz. Bir mesajı çok uzun süre kilitli ise, bir şeyler yanlış gitti ve soruşturma sonucuna varabiliriz.

Sen Sorunu arkanı.

Bunun yerine, aynı zamanda sıranın dışında şeyler alma sorunu olduğu. En kısa sürede bunu almak gibi tüm bilgileri yayınlayın. But, belli bir zamana kadar görünür olması suposed olmayan bir kural ile yayımlayabilirsiniz. Bu şekilde şeyler yapıyor kilitleme / çekişme sorunları önlemek yardımcı olabilir.

Beanstalkd iletinin sıraya bakabilirsiniz. Bunun için PHP müşterileri vardır. Beanstalkd (örn. dropr aksine) güzel özelliklerinden biri mesajları gecikme olabilir. Yani kuyruğa bir mesaj gönderebilir, ve X saniye geçtikten kadar bir müşteriye teslim edilmez.

Beanstalkd rağmen büyük bir dezavantajı var: Bu bir bellek kuyruk var. O (veya makine) kuyruğu boş ve içeriği kayıp sonra çökerse demektir. Sebat beanstalkd bir sonraki sürümü için planlanan bir özelliktir.

Online çözümleri çift:

  1. Amazon SQS.
  2. Google appengine queue system

Ben google solüsyonu (çok kullanmıyorsanız bile özgür olabilir) çok daha ucuz sanırım.

Ben de PHP / MySQL ve kullanma düşüncesinde kuyruğunu uygulama düşünüyordum:

  1. mysql get_lock kilit çeşit uygulamak.
  2. Bellek kuyrukta disk üzerinde sıra çok daha hızlı olduğu için MySQL memory heap Veri ambarı, kuyruğu koyun. Ama bilgisayar çöküyor veri kaybetme riski var.
  3. named pipes süreçleri ile iletişim kurmak için kullanın.