6

By counter it could be pageviews, downloads, number of votes etc. Basically, not very 'critical' data.

What is the 'best' way to store those information? Mysql is not a good option. What do you guys use?

Patrick
  • 939
  • 2
  • 8
  • 10

4 Answers4

10

I think I would go with Redis, because:

  • Antirediz(his nickname) is really actively developing Redis. (Every time when I look at my github dashboard he has commited some new code). He now is developing redis fulltime thanks to VMware
  • Redis is eventually persistent so the performance is kickass (first only uses memory which is fast).
  • Redis has an atomic increment operation which you need.
  • Redis has a a lot good PHP libraries. There is also one which is written as a C extension so it has really good performance. Redis website also has an overview off these extensions. Some are pure PHP code (run a litle but slower, but are easier to configure).
Alfred
  • 60,935
  • 33
  • 147
  • 186
  • hands down I would say redis. I'm doing a counter sort of thing and I'm pushing 30k commands per minute on a $20 512MB VPS. :) – James Hartig Jan 18 '10 at 05:56
  • We tried to use redis for a counters system. Redis' primary datastore is RAM, and our dataset was just too large for that to be effective. Something more like Tokyo Tyrant -- which doesn't have to keep the whole dataset in ram all the time -- probably would have been a better choice. – Frank Farmer Mar 25 '10 at 02:19
  • A simple counter can not be kept in RAM? Twitter stores almost all active tweets in memory. If you want performance I think you should pay a little cash for a memory module. Beside you can get a couple gigs of ram cheap. – Alfred Mar 25 '10 at 17:28
9

MongoDB with upserts is great for this.

If you're storing something like:

{ "url" : "www.example.com", "pageviews" : 0 }

you can atomically increment pageviews really quickly with the atomic operation $inc:

db.downloads.update({'url' : 'www.example.com'}, {'$inc' : {pageviews : 1}})

If you use upserts, you don't have to check whether a document exists before updating it. For example, if you say:

db.downloads.update({'url' : 'www.example.com'}, {'$inc' : {pageviews : 1}}, {"upsert" : true})

the document with the url www.example.com will be created if it doesn't exist (with pageviews set to 1) or, if it does exist, pageviews will be incremented. This means you don't have to worry about pre-populating the collection.

kris
  • 23,024
  • 10
  • 70
  • 79
1

The famous view counters of the 1990s used simple files to store the number. If all you need is just to store one number, anything is good enough.

stesch
  • 7,202
  • 6
  • 47
  • 62
  • 2
    If you get any sort of meaningful traffic, writing to a file on disk has concurrency issues. Unless you use file locking, but then you run the risk of lock contention. Projects like memcached exist for a reason. – Frank Farmer Jan 10 '10 at 02:43
  • 2
    But if you are just using it for a simple(low traffic) site this could work and wwill be easy to implement – Alfred Jan 13 '10 at 19:01
  • Lock contention isn't that hard. `while(!get_lock() || count > 10000) { sleep(0.001); count++ }; fread() or fwrite(); remove_lock();` Something simple like that can easily handle handle hundreds of thousands of requests per second... assuming your chosen operating system is quick at filesystem operations. – Abhi Beckert Sep 07 '12 at 22:57
-1

I would say APC or memcached are good choices.

Alix Axel
  • 151,645
  • 95
  • 393
  • 500