<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2900.2627" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=#ffffff>
<DIV>&gt; Actually, a minute delay would be a bad thing because 
replicated<BR>&gt; usrloc records, using t_replicate() would not make it in to 
peer SER<BR>&gt; server caches when the server is starting 
up.&nbsp;&nbsp;<BR></DIV>
<DIV>Yeah, I forgot about that scheme...</DIV>
<DIV>&nbsp;<BR>&gt; Given this fact, and given the fact that most SER modules do 
not hash<BR>&gt; data upon server startup [like group.so, etc, etc] we are 
starting to<BR>&gt; see little value in caching usrloc. Our MySQL server is hit 
12 times<BR>&gt; for an INVITE message and so complete caching of usrloc is of 
minimal<BR>&gt; performace gain.&nbsp;&nbsp;&nbsp; <BR>&gt; <BR>&gt; Anyhow, 
we're not in process of modifying SER so that:<BR>&gt; <BR>&gt; * when ser 
starts up usrloc is "lazy-loaded"<BR>&gt; * if a usrloc record is looked up in 
cache and is __NOT__ found, then<BR>&gt; MySQL will be queried. If found in 
MySQL then the usrloc record will<BR>&gt; be put in to cache for future 
lookups&nbsp; <BR>&gt; <BR>&gt; By doing these two things we should not have a 
problem we excessively<BR>&gt; large subscriber bases. <BR>&gt; <BR>&gt; 
Thoughts?</DIV>
<DIV>&nbsp;</DIV>
<DIV>Makes sense.&nbsp; This is how Berkeley DB and many other DBs work.&nbsp; 
In fact, the best would be to build an abstraction cache layer around all the 
query functions that have data in the DB. This way you would get the optimum 
performance/scalability.</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp; However, there is one more thing: You need to decide on 
an algorithm for selecting a usrloc record to replace when the cache is 
full.&nbsp; Do you store extra info in memory for each usrloc to make the right 
decision (ex. based on the number of lookups).</DIV>
<DIV>Also, what to do when you are storing a new location with save: Do you put 
it in the cache as well? Today this happens automatically.&nbsp; As you have 
continous registrations, you will fill up the cache with registered clients (and 
push out the ones having been called).&nbsp; What you really want is to keep the 
user locations you need (those required by lookup) in the cache.&nbsp; So I 
would suggest that in save(), you only write to the DB (and of course update the 
record if its in the cache) and that lookup() is the function that will control 
the activation and replacement of the records in the cache. </DIV>
<DIV>&nbsp;</DIV>
<DIV>I think this approach to caching is of interest also to those who do not 
have a mysql cluster, but do regular replication, for example to reduce start-up 
time.&nbsp; I believe an implementation may get pretty involved (in terms of 
important functions you need to touch).&nbsp; However, I cannot see that you 
will need to touch the core. </DIV>
<DIV>&nbsp;</DIV>
<DIV>g-)</DIV>
<DIV><BR>&gt; Paul<BR>&gt; <BR>&gt; <BR>&gt; On 5/29/05, Greger V. Teigre 
&lt;greger@teigre.com&gt; wrote:<BR>&gt; Interesting discussion.&nbsp; I believe 
most large-scale deployments (there<BR>&gt; aren't really that many...) divide 
the user base across several<BR>&gt; servers. I <BR>&gt; believe they use 20K 
users is a "good number" per server.&nbsp; So, one ser<BR>&gt; having to load 
that many records, is only if you have a cluster with<BR>&gt; no <BR>&gt; server 
divide.&nbsp; Loading all the contacts into memory is impossible to<BR>&gt; 
scale, <BR>&gt; at one point it will take too long time and take too much 
memory. <BR>&gt; So, a <BR>&gt; better architecture *for such a deployment 
scenario* would be a cache<BR>&gt; of <BR>&gt; some size and then a lookup of 
records in DB if not present in cache.<BR>&gt; Loading 330 records per second, 
you can load about 20,000 contacts in<BR>&gt; a <BR>&gt; minute, which probably 
is ok.<BR>&gt; g-)<BR>&gt; <BR>&gt; Zeus Ng wrote:<BR>&gt;&gt; See inline 
comment.<BR>&gt;&gt; <BR>&gt;&gt;&gt; Thanks for the info. I did change that 
config.h define and<BR>&gt;&gt;&gt; now it works well.<BR>&gt;&gt; <BR>&gt;&gt; 
Great to hear that the little change solve your problem.<BR>&gt;&gt; 
<BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; My newest problem is the ser start time. In my 
very<BR>&gt;&gt;&gt; non-scientific test it took ser about 25 minutes before 
it<BR>&gt;&gt;&gt; began serving requests because it was loading usrloc 
information.<BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; That was using 500000 records in 
the location table. The<BR>&gt;&gt;&gt; MySQL server was running on the same box 
as SER, which is<BR>&gt;&gt;&gt; also my workstation, so stuff like Firefox, X, 
etc, were in use.<BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; But this does bring up an 
interesting problem namely - how<BR>&gt;&gt;&gt; can ser service SIP clients 
while loading large number of<BR>&gt;&gt;&gt; usrloc records? I'm kind of 
thinking that this could be a big<BR>&gt;&gt; <BR>&gt;&gt; No, you can't. In 
fact, you will experience a temporary slow down<BR>&gt;&gt; when a hugh number 
of UA is un-registering because the table was<BR>&gt;&gt; locked during that 
period of time. I once use sipsak to register 5000<BR>&gt;&gt; users in 15s. 
When they all expired about the same time, SER hang for<BR>&gt;&gt; a while for 
locking the table to release the record from memory.<BR>&gt;&gt; <BR>&gt;&gt; 
<BR>&gt;&gt;&gt; problem. When dealing with massive user bases there is 
no<BR>&gt;&gt;&gt; such thing as a "quick restart".<BR>&gt;&gt; <BR>&gt;&gt; 
Well, that's the trade-off of memory base db. You need to balance 
the<BR>&gt;&gt; startup time verse runtime performance.<BR>&gt;&gt; 
<BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; We do have LVS fully "sip-aware" so we are 
doing true UDP<BR>&gt;&gt;&gt; load balancing based on the Call-ID header, but 
this is still<BR>&gt;&gt;&gt; a problem [potentially] with replication ucontact 
records<BR>&gt;&gt;&gt; while the server is starting up.<BR>&gt;&gt;&gt; 
<BR>&gt;&gt;&gt; I wonder if it is possible to modify the behaviour of 
usrloc<BR>&gt;&gt;&gt; so that it loads in the background while ser is 
processing<BR>&gt;&gt;&gt; SIP messages. And when lookup("location") is 
executed, usrloc<BR>&gt;&gt;&gt; searching the the ser cache and then MySQL if 
no hit is found<BR>&gt;&gt;&gt; in cache -- or something like that.<BR>&gt;&gt; 
<BR>&gt;&gt; This triggers me to bring up the common question asked on this 
list<BR>&gt;&gt; before. Can SER use just MySQL for usrloc? A similar concept 
has been<BR>&gt;&gt; done on the speeddial module. It would help load 
distribution, faster<BR>&gt;&gt; startup time and better redundancy. Of course, 
slower lookup as<BR>&gt;&gt; tradeoff.<BR>&gt;&gt; <BR>&gt;&gt; I once consider 
replacing the build-in memory base DB with MySQL<BR>&gt;&gt; memory db. However, 
that idea was dropped due to time constrain and<BR>&gt;&gt; compatability 
(postgresql) issue.<BR>&gt;&gt; <BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; Can anyone on 
serusers give some tips as to how to get ser to<BR>&gt;&gt;&gt; load usrloc 
entries optimized? I know the usual stuff like<BR>&gt;&gt;&gt; faster MySQL 
disks, faster network connection, dedicated app<BR>&gt;&gt;&gt; servers, etc, 
etc. But I'm looking for ser and/or MySQL<BR>&gt;&gt;&gt; tweaking 
hacks.<BR>&gt;&gt; <BR>&gt;&gt; Good luck on your search.<BR>&gt;&gt; 
<BR>&gt;&gt; <BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; Regards,<BR>&gt;&gt;&gt; 
Paul<BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt; <BR>&gt;&gt; <BR>&gt;&gt; 
_______________________________________________<BR>&gt;&gt; Serusers mailing 
list<BR>&gt;&gt; serusers@lists.iptel.org<BR>&gt;&gt; 
http://lists.iptel.org/mailman/listinfo/serusers</DIV></BODY></HTML>