<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hello,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I have Kamailio installed as SIP redirect for an SBC to make routing decisions.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I’m using SQLOps module with postgresql 11.5 where I have multiple tables containing each around 6M record of routing codes:<o:p></o:p></p>
<p class="MsoNormal">Code       options<o:p></o:p></p>
<p class="MsoNormal">392342  sup1|sup2|sup3<o:p></o:p></p>
<p class="MsoNormal">Where code field is of prefix_range data type and has a gist index.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I’m sending traffic of 300 CPS to SBC which is forwarding it to Kamailio, and Kamailio respond with 300 multiple choice with the routing decision.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">In normal cases, everything is going smoothly where Kamailio repsonds up to 50 ms.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">But during the process of loading data to the routing tables, Kamailio response to SBC is dramatically delayed , where for some calls it takes up to 7 seconds to respond.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Noting that during this process the data are loaded to staging tables and not to live tables used by Kamailio.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Kamailio is installed on a VM with 32GB RAM and 16 vcores.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Following configuration is used in Kamailio:<o:p></o:p></p>
<p class="MsoNormal">fork=yes<o:p></o:p></p>
<p class="MsoNormal">children=10<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">following are the customized parameters in postgresql.conf<o:p></o:p></p>
<p class="MsoNormal">max_connections = 100<o:p></o:p></p>
<p class="MsoNormal">shared_buffers = 8GB<o:p></o:p></p>
<p class="MsoNormal">effective_cache_size = 24GB<o:p></o:p></p>
<p class="MsoNormal">maintenance_work_mem = 2GB<o:p></o:p></p>
<p class="MsoNormal">checkpoint_completion_target = 0.7<o:p></o:p></p>
<p class="MsoNormal">wal_buffers = 16MB<o:p></o:p></p>
<p class="MsoNormal">default_statistics_target = 100<o:p></o:p></p>
<p class="MsoNormal">random_page_cost = 1.1<o:p></o:p></p>
<p class="MsoNormal">effective_io_concurrency = 200<o:p></o:p></p>
<p class="MsoNormal">work_mem = 5242kB<o:p></o:p></p>
<p class="MsoNormal">min_wal_size = 1GB<o:p></o:p></p>
<p class="MsoNormal">max_wal_size = 2GB<o:p></o:p></p>
<p class="MsoNormal">max_worker_processes = 16<o:p></o:p></p>
<p class="MsoNormal">max_parallel_workers_per_gather = 8<o:p></o:p></p>
<p class="MsoNormal">max_parallel_workers = 16<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Following is the routing logic I’m using:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">route{<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">if (is_method("INVITE"))              {      <o:p></o:p></p>
<p class="MsoNormal">$var(inc) = $(ct{param.value,tgrp});  <o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","CONTACT : $var(inc)" );<o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","from number : $rU" );<o:p></o:p></p>
<p class="MsoNormal">if($var(inc)!=0)<o:p></o:p></p>
<p class="MsoNormal">route(customer);<o:p></o:p></p>
<p class="MsoNormal">route(block);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">route[customer]<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">sql_query("cb", "select caid from customeridentification where  trunk='$var(inc)'", "ra");<o:p></o:p></p>
<p class="MsoNormal">$var(cid)=$dbr(ra=>[0,0]);<o:p></o:p></p>
<p class="MsoNormal">sql_result_free("ra");<o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","cid: $var(cid) \n");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">sql_query("cb", "select routetablename from carrieraccount where  caid=$var(cid)", "ra");<o:p></o:p></p>
<p class="MsoNormal">$var(tid)=$dbr(ra=>[0,0]);<o:p></o:p></p>
<p class="MsoNormal">sql_result_free("ra");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">if($var(cid)!=0) <o:p></o:p></p>
<p class="MsoNormal">route(query);<o:p></o:p></p>
<p class="MsoNormal">else <o:p></o:p></p>
<p class="MsoNormal">route(block);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">route[query]<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">#sql_query("cb", "select supplierid from route_$var(cid) where  prefix @>'$rU' order by prefix limit 1", "ra");<o:p></o:p></p>
<p class="MsoNormal">sql_query("cb", "select get_routing('$var(tid)','$rU')", "ra");<o:p></o:p></p>
<p class="MsoNormal">$var(sup)=$dbr(ra=>[0,0]);<o:p></o:p></p>
<p class="MsoNormal">sql_result_free("ra");<o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","supplieris: $var(sup) \n");<o:p></o:p></p>
<p class="MsoNormal">#$var(x)=$(var(sup){s.replace,|,}{s.len})/4;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">$var(a)=$(var(sup){s.len});<o:p></o:p></p>
<p class="MsoNormal">$var(z)=$(var(sup){s.replace,|,});<o:p></o:p></p>
<p class="MsoNormal">$var(b)=$(var(z){s.len});<o:p></o:p></p>
<p class="MsoNormal">$var(suplen)=$var(a) - $var(b);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">if($var(sup)!=0)<o:p></o:p></p>
<p class="MsoNormal">route(send);<o:p></o:p></p>
<p class="MsoNormal">else <o:p></o:p></p>
<p class="MsoNormal">route(block);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">route[send]<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","Inside Send \n");<o:p></o:p></p>
<p class="MsoNormal">$var(i)=0;<o:p></o:p></p>
<p class="MsoNormal">append_to_reply("Contact:");<o:p></o:p></p>
<p class="MsoNormal">while($var(i)<$var(suplen) + 1)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">$var(s)=$(var(sup){s.select,$var(i),|});<o:p></o:p></p>
<p class="MsoNormal">$var(s)=$(var(s){s.select,0,;});<o:p></o:p></p>
<p class="MsoNormal">append_to_reply("<sip:$rU;tgrp=$(var(s){s.ltrim})@ xxx.xxx.xxx.xxx:5060;user=phone>");<o:p></o:p></p>
<p class="MsoNormal">if($var(i)<$var(suplen)) append_to_reply(",");<o:p></o:p></p>
<p class="MsoNormal">$var(i)=$var(i)+1;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal">append_to_reply("\r\n");<o:p></o:p></p>
<p class="MsoNormal">sl_send_reply("300","Multiple Choices");<o:p></o:p></p>
<p class="MsoNormal">exit;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">route[block]<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal">xlog("L_INFO","INSIDE BLOCK" );<o:p></o:p></p>
<p class="MsoNormal">append_to_reply("Contact:<sip:$rU;tgrp=999999@xxx.xxx.xxx.xxx:5060;user=phone>\r\n");<o:p></o:p></p>
<p class="MsoNormal">sl_send_reply("300","Multiple Choices");<o:p></o:p></p>
<p class="MsoNormal">exit;<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">How can we enhance the Kamailio response in case of load on the postgresql server.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Regards,<o:p></o:p></p>
<p class="MsoNormal">Ali Taher<o:p></o:p></p>
</div>
</body>
</html>