2013-08-01 18 views
6

Ben 12a4..., c3af... gibi dize yılında birincil anahtar içeren bir tablo var. Paralel bunları işlemek istiyorum:n parçalar halinde bir altıgen endeksi Bölünmüş

process_them(1,4) on machine 1 
process_them(2,4) on machine 2 
process_them(3,4) on machine 3 
process_them(4,4) on machine 4 

Yukarıdaki tabloda tüm satırlar seçmelisiniz yaparak, birbirleriyle koordine makineler olmadan. Ben ile gelebilir en iyi fikir gibi 16 bölünmeleri geçerli: Bana 1/2, 1/4, 1/8, 1/16 gibi daha bölmelerini verir daha iyi bir fikir var mı

select * from table where id like '1%' 
... 
select * from table where id like 'e%' 
select * from table where id like 'f%' 

, Toplam satırların 1/32 vs?

Not: Bunu, kullanıcı verileri üzerinde gece işlenmesi ve bildirim gönderilmesi için yapıyorum. DB'nin kendisi üzerinde hiçbir şey düzenlemiyorum. Ve bir seferde binlerce kullanıcıyı işlemek zorundayız, bu şekilde verimli olmayacak şekilde ince taneli bir şekilde bölünemez.

+0

Makinelerde bir artış sistemi kimliği varsa, bunu bir LIMIT deyiminde kullanabilirler. Ama bu muhtemelen "koordinasyon" olarak sayılır. IMHO, çevreleriyle ilgili bir şey bilmeleri gerektiğini önerdiğinizden daha iyi bir şey elde etmek için. – mabi

+0

Dağıtılmış veritabanı en iyi çözüm olduğunu düşünüyorum. – Suleman

cevap

0

en basit yaklaşım, en az iki devlet ile, masanıza bir status sütun ekleyerek olacaktır:

0 = pending 
1 = *not* pending 

Daha sonra her işlem parçacığı mümkün "yedek" olarak işlemek için satır küçük parti olacaktır. Genel iş akışı olacaktır: işlerinizin gerçek işlem süresine bağlı olarak
BEGIN TRANSACTION; 
SELECT * FROM queue WHERE status = 0 LIMIT 5 FOR UPDATE; -- load 5 pending items 
-- if no pending item: terminate here 
-- save this list of jobs in your application layer here 
UPDATE queue SET status = 1 WHERE id IN (@id_list); -- list of id's from the previous step 
COMMIT; 
-- process your jobs here 
-- loop 

, bu yaklaşım tatmin edici olamayacak kadar ağır bir yükü olabilir. İlk adımda LIMIT'u bir defada daha fazla iş yüklemek, göreceli yükü azaltmak ve süreçler arasında muhtemelen daha az dengeli iş dağılımı maliyetini artırmak.

+0

Verileri bizzat güncellemez. Ve eşzamanlı olarak 'güncelleme için seç' gibi, taahhüt/iptal edilene kadar birbirini kilitlerdi. Paralel olarak yapılmayacak. – aitchnyu

+0

Hayır, en kötü durum senaryosunda, eşzamanlı iş parçacıkları bir iş parçacığının işleri yüklemesi ve durumlarını ("SELECT" ve "UPDATE") güncelleştirmesi için gereken süreyi, yani tablonun uygun şekilde birkaç milisaniye kadar kilitlenmesini sağlar. endekslendi. "İşlerinizi burada işleyin" bölümüne dikkat edin, bölüm işlemin dışında. İşleminiz için yeni bir sütun eklemenin ve işlemenin yalnızca “verileri kendisinin değiştirmesi” olarak kabul edilmesi gerektiğinden emin değilim, ancak bunun bazı durumlarda bir yokluk olabileceğini anlıyorum. – RandomSeed

2

Temiz bir fikir ...

Eğer (Orada kaçırılmış satır asla) ve ddl değişiklik yapılmadan consitently, hızla makul iyi dağıtılmış şekilde satırları distrubute için bir MD5 hash kullanabilirsiniz.

*let n = number of desired partitions. Use the following sql to 
*let s = salt, expirementally chosen to provide the best distribution based on key allocation pattern. 
SELECT * FROM TABLE WHERE mod(cast(conv(md5(concat(s, Priamry_Key)), 16, 10), n) = 0; 
SELECT * FROM TABLE WHERE mod(cast(conv(md5(concat(s, Priamry_Key)), 16, 10), n) = 1; 
... 
... 
SELECT * FROM TABLE WHERE mod(cast(conv(md5(concat(s, Priamry_Key)), 16, 10), n) = (n-1); 

Bu

iyi sonuçları ile üretim enviornments bir kaç kez uygulanan gördük bir yaklaşımdır.

Buradaki SQL test edilmediyse, sytax üzerinde hiçbir garanti yapmıyorum.