[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Mutithreading to implement near 7000 to 10000 mssage per min

Kaja Mohaideen

8/14/2008 5:23:00 AM

Hello,

we want to process 7000 to 10000 message and store it to the Database
perminute. we are trying through threads. can you please help me how we
do?

Regards
Kaja Mohaidee.A
Trichy
--
Posted via http://www.ruby-....

7 Answers

Robert Klemme

8/14/2008 9:23:00 AM

0

2008/8/14 Michael T. Richter <ttmrichter@gmail.com>:
> On Thu, 2008-08-14 at 14:22 +0900, Kaja Mohaideen wrote:
>
> we want to process 7000 to 10000 message and store it to the Database
> perminute. we are trying through threads. can you please help me how we
> do?
>
> Use a quick language that's designed for massively parallel operations, not
> one of the slower scripting languages without proper support for
> parallelism.

There may be a few ways to get this working with Ruby:

1. use Ruby to create a CSV file or similar which is then loaded into
the database via the database's bulk loader.

2. if there is support for batch operations in DBD/DBI these might work as well.

Since this task is mostly IO bound (unless of course there are
expensive operations to be done on those messages), Ruby threads are
not too unlikely to work in this scenario.

> I'm not trying to be glib here (although I may well be succeeding anyway).
> What you are saying here looks an awful lot to me like "I want to hammer in
> this screw here. Which wrench is best for the job?" Select your tools
> appropriately for the problem. Don't try to reforge your wrenches into
> bizarre combination screwdriver-hammers.

Well, maybe Kaja is just experimenting and trying out to which limits
he / she can push Ruby. :-)

Kind regards

robert


--
use.inject do |as, often| as.you_can - without end

M. Edward (Ed) Borasky

8/14/2008 1:28:00 PM

0

On Thu, 2008-08-14 at 16:52 +0900, Michael T. Richter wrote:
> On Thu, 2008-08-14 at 14:22 +0900, Kaja Mohaideen wrote:
> > we want to process 7000 to 10000 message and store it to the Database
> > perminute. we are trying through threads. can you please help me how we
> > do?
>
> Use a quick language that's designed for massively parallel
> operations, not one of the slower scripting languages without proper
> support for parallelism.
>
> I'm not trying to be glib here (although I may well be succeeding
> anyway). What you are saying here looks an awful lot to me like "I
> want to hammer in this screw here. Which wrench is best for the job?"
> Select your tools appropriately for the problem. Don't try to reforge
> your wrenches into bizarre combination screwdriver-hammers.

Yes ... Erlang / Mnesia should be able to handle this, and then you
could write some Ruby code to extract the messages from Mnesia to a
"regular" RDBMS if needed.
--
M. Edward (Ed) Borasky
ruby-perspectives.blogspot.com

"A mathematician is a machine for turning coffee into theorems." --
Alfréd Rényi via Paul ErdÅ?s


Ezra Zygmuntowicz

8/14/2008 6:59:00 PM

0


On Aug 14, 2008, at 6:28 AM, M. Edward (Ed) Borasky wrote:

> On Thu, 2008-08-14 at 16:52 +0900, Michael T. Richter wrote:
>> On Thu, 2008-08-14 at 14:22 +0900, Kaja Mohaideen wrote:
>>> we want to process 7000 to 10000 message and store it to the
>>> Database
>>> perminute. we are trying through threads. can you please help me
>>> how we
>>> do?
>>
>> Use a quick language that's designed for massively parallel
>> operations, not one of the slower scripting languages without proper
>> support for parallelism.
>>
>> I'm not trying to be glib here (although I may well be succeeding
>> anyway). What you are saying here looks an awful lot to me like "I
>> want to hammer in this screw here. Which wrench is best for the
>> job?"
>> Select your tools appropriately for the problem. Don't try to
>> reforge
>> your wrenches into bizarre combination screwdriver-hammers.
>
> Yes ... Erlang / Mnesia should be able to handle this, and then you
> could write some Ruby code to extract the messages from Mnesia to a
> "regular" RDBMS if needed.


I'd say use rabbitmq with the ruby amqp library, this will allow you
to easily push many thousands of messages/sec into the rabbitmq
message bus and then you can have a set of fanout workers consuming
the queues on the other side and putting the items in the database.

-Ezra


ara.t.howard

8/14/2008 7:06:00 PM

0


On Aug 13, 2008, at 11:22 PM, Kaja Mohaideen wrote:

> Hello,
>
> we want to process 7000 to 10000 message and store it to the Database
> perminute. we are trying through threads. can you please help me how
> we
> do?
>
> Regards
> Kaja Mohaidee.A
> Trichy


buffer them and insert them in a transaction 1000 at a time. even
with ruby this should be a peice of cake.

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Martin DeMello

8/14/2008 7:11:00 PM

0

On Thu, Aug 14, 2008 at 12:06 PM, ara.t.howard <ara.t.howard@gmail.com> wrote:
>
> buffer them and insert them in a transaction 1000 at a time. even with ruby
> this should be a peice of cake.

Do any of the ruby db libraries offer support for doing this efficiently?

martin

ara.t.howard

8/14/2008 8:57:00 PM

0


On Aug 14, 2008, at 1:10 PM, Martin DeMello wrote:

> On Thu, Aug 14, 2008 at 12:06 PM, ara.t.howard
> <ara.t.howard@gmail.com> wrote:
>>
>> buffer them and insert them in a transaction 1000 at a time. even
>> with ruby
>> this should be a peice of cake.
>
> Do any of the ruby db libraries offer support for doing this
> efficiently?
>
> martin

pretty much all of them


cfp:~/rails_root > cat a.rb
size = Integer(ARGV.shift || 10_000)

messages = Array.new(size).map{ rand.to_s }

Db = "#{ RAILS_ROOT }/db/#{ RAILS_ENV }.sqlite3"


# using sqlite directly
#
Message.delete_all
sql = messages.map{|message| "insert into messages(content)
values(#{ message.inspect });"}.join("\n")

a = b = response = nil
IO.popen("sqlite3 #{ Db } 2>&1", "r+") do |sqlite3|
a = Time.now.to_f
sqlite3.puts "begin;"
sqlite3.puts sql
sqlite3.puts "end;"
sqlite3.flush
sqlite3.close_write
response = sqlite3.read
b = Time.now.to_f
end

abort response unless $?.exitstatus.zero?

puts "using sqlite3"
puts "elapsed: #{ b - a }"
puts "count: #{ Message.count }"

# using ar
#
Message.delete_all
a = Time.now.to_f

Message.transaction do
messages.each{|message| Message.create! :content => message}
end

b = Time.now.to_f

puts "using ar"
puts "elapsed: #{ b - a }"
puts "count: #{ Message.count }"



cfp:~/rails_root > ./script/runner a.rb
using sqlite3
elapsed: 0.222311019897461
count: 10000

using ar
elapsed: 7.75591206550598
count: 10000

0.2 seconds for 100000 records seems plenty fast to me. 7 seconds not
so much.



a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Jeremy Hinegardner

8/14/2008 9:26:00 PM

0

On Fri, Aug 15, 2008 at 05:56:46AM +0900, ara.t.howard wrote:
>
> On Aug 14, 2008, at 1:10 PM, Martin DeMello wrote:
>
>> On Thu, Aug 14, 2008 at 12:06 PM, ara.t.howard <ara.t.howard@gmail.com>
>> wrote:
>>>
>>> buffer them and insert them in a transaction 1000 at a time. even with
>>> ruby this should be a peice of cake.
>>
>> Do any of the ruby db libraries offer support for doing this efficiently?
>>
>> martin
>
> pretty much all of them
>

[...]

> cfp:~/rails_root > ./script/runner a.rb
> using sqlite3
> elapsed: 0.222311019897461
> count: 10000
>
> using ar
> elapsed: 7.75591206550598
> count: 10000
>
> 0.2 seconds for 100000 records seems plenty fast to me. 7 seconds not so
> much.

If your standard of performance is 10,000 records inserted in a minute, any
database should be able to satisfy your requirements.

And here's the amalgalite version of ara's test... embedded sqlite in a ruby
extension.

% cat am_inserts.rb
#!/usr/bin/env ruby
require 'rubygems'
require 'amalgalite'

size = Integer(ARGV.shift || 10_000)

messages = Array.new(size).map{ rand.to_s }

Db = "speed-test.db"

FileUtils.rm_f Db if File.exist?( Db )
db = Amalgalite::Database.new( Db )
db.execute(" CREATE TABLE messages(content); ")

before = Time.now.to_f
db.transaction do |db_in_trans|
messages.each do |m|
db_in_trans.execute("insert into messages(content) values( #{m} )")
end
end
after = Time.now.to_f
elapsed = after - before
mps = size / elapsed
puts "#{"%0.2f" % elapsed} seconds to insert #{size} records at #{"%0.2f" % mps} records per second"

% ruby am_inserts.rb
0.38 seconds to insert 10000 records at 25999.01 records per second

% ruby am_inserts.rb 100000
3.80 seconds to insert 100000 records at 26344.71 records per second

enjoy,

-jeremy

--
========================================================================
Jeremy Hinegardner jeremy@hinegardner.org