<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
    <channel>
        <title>CUBRID Blog</title>
        <link>http://blog.cubrid.org</link>
        <description>Latest stories in the CUBRID Blog</description>
        <language>en</language>
        <pubDate>Wed, 07 Sep 2011 03:12:42 +0900</pubDate>
        <lastBuildDate>Tue, 22 May 2012 01:36:30 +0900</lastBuildDate>
        <generator>XpressEngine 1.4.4.1</generator>
                        										        <item>
            <title>The Story behind LINE App Development</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/the-story-behind-line-app-development/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/the-story-behind-line-app-development/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/the-story-behind-line-app-development/#comment</comments>
                                    <description><![CDATA[<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/690/355/line_app_android.jpeg" alt="line_app_android.jpeg" width="727" height="295" editor_component="image_link" /></p>

<p>If you have a smartphone, you must be using <a href="http://line.naver.jp/en/" target="_self">LINE</a>,&nbsp;<a href="http://www.kakao.com/talk" target="_self">KakaoTalk</a>, or&nbsp;<a href="http://www.whatsapp.com/" target="_self">Whatsapp</a>&nbsp;messaging app, if not all of them. But unlike KakaoTalk and Whatsapp, <b>LINE</b> also allows users to <b>call other LINE users for free</b>&nbsp;- great value-added service, isn't it!? Today I will explain more about LINE, its background story as well as how its developers use <a href="/blog/tags/NoSQL/" target="_self">NoSQL</a> together with an in-memory data storage to manage&nbsp;billions of user messages per month!</p><h2>Behind Story</h2><p>So, you already know about the first advantage of LINE - <b>free calling service</b>. But there is another one which gives even more convenience for users - it is available not only on leading mobile platforms (iOS and Android), but also on <b>Mac OS X and&nbsp;Windows</b>&nbsp;desktop operating systems. Now in order to send a message to your friend, you no longer need to take out your mobile phone and type on its tiny keyboard. You can use the <b>desktop LINE</b> to make the conversation fast and more convenient! You type on your computer, your friends and family read the message on their mobile or desktop app. Staying in touch for FREE has never been easier.&nbsp;I am sold!</p><p>Now the main question: <b>how LINE app was created?</b></p><p>It may sound somewhat bizarre but it is all about the 2011 Japan&nbsp;Earthquake. You all know how tragic it was. Communication was disrupted,&nbsp;major damage was caused to&nbsp;many buildings, roads and transportation systems. In such situations cell phones still work&nbsp;but service is sketchy.&nbsp;Data works better than voice. This was the impetus to my colleagues at <a href="http://www.nhncorp.jp/" target="_self">NHN Japan</a> to design an app accessible on smartphones, tablet, and&nbsp;PC, which would work on data network and provide&nbsp;continuous and&nbsp;<b>free</b>&nbsp;instant&nbsp;messaging and calling service.</p><p><img src="http://www.cubrid.org/files/attach/images/220547/690/355/line_app_logo.png" alt="line_app_logo.png" width="83" height="32" style="float:left;margin-right:10px" editor_component="image_link" />The name <b>LINE</b> was originated from the fact that after the incident people had to&nbsp;<i style="font-weight: bold; ">line up</i>&nbsp;outside of public phones, because in Japan the public phones "are&nbsp;<a href="http://www.computerworld.com/s/article/9214203/_Massive_damage_from_Japan_quake_hits_communications" target="_self">programmed</a> to take priority over networks during and after an earthquake".</p><p>Later in June 2011 LINE app was launched.</p><h2>LINE Today</h2><p style="text-align: center;"><a href="http://thenextweb.com/asia/2012/04/18/japanese-messaging-app-line-passes-30-million-registered-users-sees-10-million-downloads-in-6-weeks/" target="_self"><img src="http://www.cubrid.org/files/attach/images/220547/690/355/line_app_30_million_users.png" alt="line_app_30_million_users.png" width="520" height="246" editor_component="image_link" /></a><br /></p><p>Today <b>LINE</b> is one of the most popular beautifully designed instant messaging and calling app available for <a href="http://itunes.apple.com/us/app/line/id443904275?mt=8" target="_self">iOS</a>, <a href="https://play.google.com/store/apps/details?id=jp.naver.line.android&amp;feature=search_result#?t=W251bGwsMSwxLDEsImpwLm5hdmVyLmxpbmUuYW5kcm9pZCJd" target="_self">Android</a>, <a href="https://t.line.naver.jp/en/login" target="_self">tablet</a>, and <a href="http://line.naver.jp/en/" target="_self">desktop</a> users. It took only nine months for LINE to overcome <b>30 million registered users</b> milestone. At the time of writing this article LINE has already 36 million users worldwide and is recognized as being a "Fast and Light" messenger that is considered as the "<a href="https://play.google.com/store/apps/details?id=jp.naver.line.android&amp;hl=en" target="_self">The Number 1 Free App</a>" in many countries, especially in South East Asia.</p><p>LINE app allows group chatting with up to 100 people at once, sending photo video files as well as location info, making free voice calls both on Wi-Fi and cellular network. But one of the greatest values in LINE is its <a href="http://campaign.naver.com/linesticker/en" target="_self">250+ expressive sticker and emotions collection</a>&nbsp;which make chatting even more exciting and fun.</p><h2>Database Storage for Instant Messaging App</h2><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/690/355/line_total_registered_users.png" alt="line_total_registered_users.png" width="500" height="230" editor_component="image_link" /></p><p>With increasing number of LINE users, the number of chat messages to store grows exponentially (<i>see the graph below</i>). These days LINE needs to store billions of rows in a database every month. However, back in early development stage LINE developers had anticipated the service load&nbsp;at most&nbsp;from only 1 million registered users. With such assumptions the developers had deployed <a href="http://redis.io/" target="_self">Redis</a>, an in-memory key-value store, which provides synchronous and asynchronous replication and enables DB administrators to&nbsp;take&nbsp;periodical&nbsp;disk snapshots.</p><p style="text-align: center;">&nbsp;<img src="http://www.cubrid.org/files/attach/images/220547/690/355/rows_stored_in_storage_per_month.png" alt="rows_stored_in_storage_per_month.png" width="500" height="289" editor_component="image_link" />
</p><p>Since Redis does not provide server-side sharding, LINE developers had to implement sharding on the client side and manage it with ZooKeeper. Thus, the entire LINE storage stack initially was based on single Redis cluster consisting of 3 nodes sharded on the application layer. With the growing service, more nodes were added to the cluster.</p><p>However, everything was changed around October 2011 when LINE started to experience extreme load due to unexpected growth worldwide (<i>see above graphs</i>). This have caused some outages, and delay in message delivery. The problem was in the core of Redis, in the fact that it is an in-memory store, which, unlike persistent storage systems, requires more servers. Managing LINE's tremendous growth with Redis would cost an arm and a leg. It was critical to find an alternative solution which would provide high scalability and availability at a relatively less cost.</p><p>To solve this problem, LINE developers had first identified the types of data they have to store depending on how much availability and scalability were important for each type. As a result they came to a conclusion that:</p><p></p><ol><li>for&nbsp;<b style="font-style: italic; ">user </b><i><b>messages&nbsp;in delivery queue</b></i>&nbsp;<i>availability</i>&nbsp;is critical;</li><li>for&nbsp;<i><b>user profile info</b></i> as well as <i><b>contacts</b></i> and <i><b>groups</b></i>&nbsp;both <i>scalability</i> and <i>availability</i> are important;</li><li>for <b><i>messages in the Inbox</i></b>&nbsp;as well as <b><i>change-sets of (2)</i></b> due to its massive size <i>scalability</i> is vital.</li></ol><p></p><p>To achieve <b>availability</b> LINE developers chose to stick with&nbsp;<b>Redis</b>&nbsp;in-memory data store. For scalability they had three options: HBase, Cassandra, and MongoDB.</p>

<ul>
<li><strong>HBase</strong></li>
<ul>
<li>pros: </li>
<ul>
<li>Best matches the requirements</li>
<li>Easy to operate (Storage system built on DFS, multiple ad hoc partitions per server)</li>
</ul>
<li>cons: </li>
<ul>
<li>Random read and deletion are somewhat slow.</li>
<li>Slightly lower avaiability (there’re some SPOF)</li>
</ul>
</ul>
<li><strong>Cassandra</strong></li>
<ul>
<li>pros: </li>
<ul>
<li>Also suitable for dealing with the latest workload</li>
<li>High Availability (decentralized architecture, rack/DC-aware replication)</li>
</ul>
<li>cons: </li>
<ul>
<li>High operation costs due to weak consistency</li>
<li>Counter increments are expected to be slightly slower. </li>
</ul>
</ul>
<li><strong>MongoDB</strong></li>
<ul>
<li>pros: </li>
<ul>
<li>Auto sharding, auto failover</li>
<li>A rich range of operations (but LINE storage doesn’t require most of them)</li>
</ul>
<li>cons: </li>
<ul>
<li>NOT suitable for the timeline workload (B-tree indexing)</li>
<li>Ineffective disk and network utilization</li>
</ul>
</ul>
</ul>

<p>Finally out of three, <b>HBase</b> became the successor as a <b>primary storage</b>&nbsp;for the third type of their user data&nbsp;on top of HDFS. <b>Sharded Redis</b> is still running as a <b>front-end cache</b> for data stored in HBase and as a <b>primary storage</b> for user profile, contacts and groups. Below is the current LINE storage stack architecture.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/690/355/line_storage_stack.jpg" alt="line_storage_stack.jpg" width="700" height="412" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>LINE storage stack: over 600 nodes and growing.</b></p><p>LINE developers at NHN Japan have posted a very detailed <a href="http://tech.naver.jp/blog/?p=1420" target="_self">blog article</a> where they explain how everything is designed, how they had migrated from original Redis based architecture to HBase based architecture. You are highly encouraged to read this article if you would like to learn more about how they have installed and configured separate components of their storage stack.</p>]]></description>
                        <pubDate>Tue, 22 May 2012 17:32:40 +0900</pubDate>
                        <category>LINE</category>
                        <category>database</category>
                        <category>scalability</category>
                        <category>availability</category>
                        <category>NHN</category>
                        <category>NoSQL</category>
                        <category>Hadoop</category>
                        <category>HBase</category>
                        <category>Cassandra</category>
                        <category>MongoDB</category>
                        <category>KakaoTalk</category>
                        <category>WhatsApp</category>
                                </item>
        										        <item>
            <title>Comprehensive Overview of Top 14 Content Management Systems</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/comprehensive-overview-of-top-14-content-management-systems/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/comprehensive-overview-of-top-14-content-management-systems/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/comprehensive-overview-of-top-14-content-management-systems/#comment</comments>
                                    <description><![CDATA[<p><strong>Update: </strong>added the <em>Distinguished clients</em> for DotNetNuke.</p>

<p>These days many websites (<em>in fact, millions</em>) are implemented by the use of popular open source content management systems (CMS). I would say, for <em>everything</em> <em>you would imagine your site doing</em>, there is one or another CMS which can do that. Thus, the reason for choosing a particular one depends on the tasks you want to accomplish. For blogs there is a common sense of using WordPress blog management system, for large scale websites Drupal CMS is perceived to be a better fit, while Joomla CMS is easier to learn for newbies. .NET developers prefer alternative DonNetNuke or umbraco CMS. Besides these, CMS Made Simple and Liferay are amongst the most popular content management systems based on the number of the number of downloads. Elgg and MODx are amongst the rising stars.</p>

<p>I will not tell you what a CMS is. If you want to learn, see the <a title="Wikipedia: Content management system" href="http://en.wikipedia.org/wiki/Content_management_system" target="_blank">CMS Wikipedia page</a>. In this blog I will give a comprehensive overview of top 14 content management systems based on the number of weekly downloads, installations, and brand familiarity. The full statistical data can be found in the 2010 OPEN SOURCE CMS MARKET SHARE REPORT by water&amp;stone (2010). The report is distributed under the <a title="Creative Commons Attribution-Noncommercial License (3.0)" href="http://creativecommons.org/licenses/by-nc/3.0/" target="_blank">Creative Commons Attribution-Noncommercial License</a> (3.0).</p>

<p>Today we will cover <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#drupal">Drupal</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#joomla">Joomla</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#modx">MODx</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#wordpress">WordPress</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#dotnetnuke">DotNetNuke</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#umbraco">umbraco</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#liferay">Liferay</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#typo3">TYPO3</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#cmsmadeeasy">CMS Made Simple</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#movabletype">MOVABLE TYPE</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#plone">Plone</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#ezpublish">eZ Publish</a>, <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#concrete5">concrete5</a>, and <a href="http://blog.cubrid.org/web-2-0/comprehensive-overview-of-top-14-content-management-systems/#alfresco">Alfresco</a> content management systems. You might already be familiar with some of these, while some can be new to you. I bet you will be surprised to learn that some unknown for you systems suit your requirements much better than those you have got to use so far (my personal experience). So, let's learn about each of them, and <em>do not forget to leave your comments below on what other CMS should have been included in this list and why</em>.</p>

<a name="more"></a>
<p></p>

<p></p><blockquote><strong>Note:</strong><em> the order of the CMS does not represent its quality, performance, or superiority over the other. They are numbered to give a better perception to readers. The users feedback and opinions are retrieved from Stack Overflow, thus can be subjective as they are based on personal views and preferences.</em></blockquote><p></p>

<p></p><h2># 1: Drupal</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://drupal.org/" target="_blank"><img title="Drupal" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/drupal.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site:</strong> <a title="Drupal - Open Source CMS" href="http://drupal.org/" target="_blank">http://drupal.org/</a></p>

<p>1% of all websites on the Internet are based on this platform.  An estimated 7.2 million sites were powered by Drupal as of July 2010. Drupal started out in 2001. In one year from May 2007 to April 2008, Drupal was downloaded from their official site more than 1.4 million times, an increase of approximately 125% from the previous year.</p>

<p><strong>Weekly downloads:</strong> 33,671 (<em>ranked #3 after Joomla and before DotNetNuke</em>).</p>

<p><strong>Installations:</strong> 575 according to the survey (<em>#3 after WordPres and before DotNetNuke</em>), but 1.4% (<em>#3 after Joomla and before Typo3</em>) of Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> Drupal is known to be <em>the #3 most familiar content management system</em>.</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>You can manage multiple sites with Drupal in multiple languages. You can use it for blogging site, corporate site, personal site, gallery, briefly, whatever you imagine.</li>
	<li>You can easily manage your site users, providing standard registration, including OpenID support. You can set various access control rules to limit the activity of your site users.</li>
	<li>Provides multiple-level menu system, template customization, advanced search, RSS feed aggregator.</li>
	<li>Officially Drupal supports several databases including MySQL, PostgreSQL, MariaDB, and SQLite.</li>
	<li>To increase its performance, you can use caching. At the same time it provides high security with notifications about the new update releases.</li>
	<li>Provides Search Engine Friendly descriptive URLs.</li>
	<li>Powered by jQuery JavaScript framework.</li>
</ul>
<strong>Extensions:</strong> over 7,000 free community-contributed addons, known as contrib modules.<p></p>

<p><strong>Distinguished Clients:</strong></p>

<p></p><ul>
	<li><a title="The White House of the United States of America" href="http://www.whitehouse.gov/" target="_blank">http://www.whitehouse.gov/</a></li>
	<li><a href="http://data.gov.uk/" target="_blank">http://data.gov.uk/</a></li>
	<li><a href="http://www.ubuntu.com/" target="_blank">http://www.ubuntu.com/</a></li>
	<li><a href="http://www.alrc.gov.au/" target="_blank">http://www.alrc.gov.au/</a></li>
	<li><a href="http://www.nysenate.gov/" target="_blank">http://www.nysenate.gov/</a></li>
	<li><a href="http://london.gov.uk/" target="_blank">http://london.gov.uk/</a></li>
	<li><a href="http://www.rutgers.edu/" target="_blank">http://www.rutgers.edu/</a></li>
	<li><a href="http://www.economist.com/" target="_blank">http://www.economist.com/</a></li>
	<li><a href="http://wfp.org/" target="_blank">http://wfp.org/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>More difficult to master especially for newbies. It's more for advanced users. Though the new Drupal 7 claims to provide significantly improved usability (<em>maybe more toward WordPress style</em>). To achieve this, they hired web designers to specifically address the UX problems it had in previous versions.</li>
	<li>New major releases are not quite backward compatible. More focus on new features and functionality. External module developers should take care of compatibility themselves, except for data representation, which Drupal is intended to keep same.</li>
	<li>Drupal is often compared with Joomla and is perceived to be a bit slower. Though this depends on the type of website you develop. However, leveraging its caching and gzipping technologies, it is possible to achieve quite impressive results.</li>
	<li>jQuery, the default JavaScript framework in Drupal, allows to use alternative Mootools framework at the same time.</li>
</ul>
<h2># 2: Joomla</h2><p></p>

<p><a title="Joomla" href="http://www.joomla.org/" target="_blank"><img title="Joomla" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/joomla.png" width="701" height="325" editor_component="image_link"/></a></p>

<p><strong>Official site:</strong> <a href="http://www.joomla.org/" target="_blank">http://www.joomla.org/</a></p>

<p>Joomla is the result of a fork of Mambo CMS on August 17, 2005. Within its first year of release, Joomla had been downloaded 2.5 million times.</p>

<p><strong>Weekly downloads:</strong> 113,836 (<em>ranked #2 after WordPress and before Drupal</em>).</p>

<p><strong>Installations:</strong> 1,297 according to the survey (<em>#1 before WordPress</em>), but 2.5% (<em>#2 after WordPress and before Drupal</em>) of Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> Joomla is known to be <em>the #1 most familiar content management system</em>.</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>You can manage multiple site with Joomla in multiple languages natively (since Joomla 1.6). You can use it for blogging site, corporate site, personal site, gallery, briefly, whatever you imagine.</li>
	<li>You can easily manage your site users, providing standard registration, including Google OpenID support. Full support for Access Control List.</li>
	<li>Provides Multiple-level menu and content category system, template customization, advanced search, RSS feed aggregator.</li>
	<li>Officially supports only MySQL.</li>
	<li>Page cashing for increased performance.</li>
	<li>Provides moderate descriptive URLs (<em>still not fully customizable as you can do in WordPress</em>).</li>
	<li>Powered by MooTools JavaScript framework.</li>
</ul>
<strong>Extensions:</strong> There are over 6,000 free and commercial plugins available from the official site.<p></p>

<p><strong>Distinguished Clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.linux.com/" target="_blank">http://www.linux.com/</a></li>
	<li><a href="http://www.itwire.com/" target="_blank">http://www.itwire.com/</a></li>
	<li><a href="http://www.quizilla.com/" target="_blank">http://www.quizilla.com</a></li>
	<li><a href="http://www.ihop.com/" target="_blank">http://www.ihop.com</a></li>
	<li><a href="http://gsas.harvard.edu/" target="_blank">http://gsas.harvard.edu</a></li>
	<li>Citibank (Financial institution      intranet) - Not publicly accessible</li>
	<li><a href="http://www.greenmaven.com/" target="_blank">http://www.greenmaven.com</a></li>
	<li><a href="http://www.outdoorphotographer.com/" target="_blank">http://www.outdoorphotographer.com</a></li>
	<li><a href="http://www.playshakespeare.com/" target="_blank">http://www.playshakespeare.com</a></li>
	<li><a href="http://www.sensointeriors.co.za/" target="_blank">http://www.sensointeriors.co.za</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>More intuitive and easy to use than Drupal, though still not like WordPress.</li>
	<li>Powerful. Fully-fledged content management system, so you can create whatever site you want.</li>
	<li>Really strong security. If security problems found, immediately fixed.</li>
	<li>The new Joomla 1.6 release is expected to be faster, more convenient, with more features.</li>
	<li>Its strong dependency on Mootools JavaScript framework sometimes bothers users as Joomla does not give easy workaround to disable it and use jQuery instead.</li>
	<li>Support of only one database, limits Joomla a lot in terms of the number of users. However, this is a compromise for high optimizations for MySQL, thus increased overall performance.</li>
	<li>Does not allow to fully customize URLs - a must feature for CMS.</li>
</ul>
<h2>#3: modx</h2><p></p>

<p><a title="modx" href="http://www.modxcms.com/" target="_blank"><img title="modx" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/modx.png" width="701" height="325" editor_component="image_link"/></a></p>

<p><strong>Official site: </strong><a href="http://www.modxcms.com/" target="_blank">http://www.modxcms.com/</a></p>

<p><strong>modx</strong> is not just an open source CMS but also a web application framework. Raymond Irving and Ryan Thrash began the MODx CMS project in 2004 as a fork of Etomite. In 2008 MODx users created a new logo and branding for the project. Now MODx allows for full segregation of content (plain HTML), appearance and behavior (standards compliant CSS and JavaScript) and logic (PHP, snippets).</p>

<p><strong>Weekly downloads:</strong> 4,500 (<em>ranked #11 after umbraco and before Tiki</em>).</p>

<p><strong>Installations:</strong> 58 according to the survey (<em>#12 after eZ Publish and before umbraco</em>), has less than 0.1% among the Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> #14 (<em>before Liferay and after eZ Publish</em>).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>As with Joomla, modx officially supports only MySQL database.</li>
	<li>Not just CMS but a PHP framework for Web.</li>
	<li>Freedom to choose jQuery, Mootools, ExtJS, Prototype or any other JavaScript library.</li>
	<li>Supports PHP 4.3.11 and above.</li>
	<li>Complete control of all metadata and URL structure for SEO (Search Engine Optimization).</li>
	<li>Unlimited hierarchical page depth.</li>
	<li>Can create custom fields and widgets for templates.</li>
	<li>Role-based permissions for the Manager.</li>
	<li>Ability to customize the Manager on a per-deployment basis.</li>
	<li>Ecommerce integration via Foxy Cart.</li>
</ul>
<strong>Extensions:</strong> 622, also known as add-ons.<p></p>

<p><strong>Distinguished Clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.pippatoledo.com/" target="_blank">http://www.pippatoledo.com/</a></li>
	<li><a href="http://www.aquevix.com/" target="_blank">http://www.aquevix.com/</a></li>
	<li><a href="http://www.not1bug.com/" target="_blank">http://www.not1bug.com/</a></li>
	<li><a href="http://everlight-uva.com/" target="_blank">http://everlight-uva.com/</a></li>
	<li><a href="http://www.tritopora.ru/" target="_blank">http://www.tritopora.ru/</a></li>
	<li><a href="http://www.strategische-webloesungen.de/" target="_blank">http://www.strategische-webloesungen.de/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>Good to have a choice for favorite JavaScript framework.</li>
	<li>Light CMS solution (but not necessarily the fastest).</li>
	<li>PHP 4 support for developers mean that a lot of compromises had to be made in terms of OOP (Object Oriented Programming) in order to offer PHP 4 support .</li>
	<li>Nice to have freedom to set custom URL.</li>
</ul>
<h2>#4: WordPress</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://wordpress.org/" target="_blank"><img title="WordPress" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/wordpress.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site:</strong> <a href="http://wordpress.org/" target="_blank">http://wordpress.org/</a></p>

<p>WordPress was first released on May 27, 2003, by Matt Mullenweg as a fork of b2/cafelog. As of August 2010, version 3.0 had been downloaded over 12.5 million times. Nowadays, known as the #1 CMS for blogging.</p>

<p><strong>Weekly downloads:</strong> 983,625 (<em>ranked #1 before Joomla</em>).</p>

<p><strong>Installations:</strong> 1,012 according to the survey (<em>#2 after Joomla and before Drupal</em>), but 12.9% of the Alexa Top 1 million sites (<em>#1 before Joomla</em>).</p>

<p><strong>Brand Familiarity:</strong> #2 (<em>after Joomla and before Drupal</em>).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Highly optimized for blogging.</li>
	<li>Custom and easy to switch themes.</li>
	<li>Users can re-arrange widgets without editing PHP or HTML code.</li>
	<li>Official support for only MySQL.</li>
	<li>Custom URL, clean permalink structure, excellent for SEO.</li>
	<li>Nested, multiple categories to articles.</li>
	<li>Support for tagging. Advanced search by tags.</li>
	<li>Highly intuitive UI (User Interface).</li>
	<li>jQuery JavaScript framework.</li>
	<li>Supports the Trackback and Pingback standards for displaying links to other sites that have themselves linked to a post or article.</li>
	<li>Rich plugin architecture which allows users and developers to extend its functionality beyond the features that come as part of the base install.</li>
</ul>
Native applications exist for Android, iPhone/iPod Touch,<a href="http://en.wikipedia.org/wiki/WordPress#cite_note-6" target="_blank"></a> and BlackBerry which provide access to some of the features in the WordPress Admin panel and work with WordPress.com and many WordPress.org blogs.<p></p>

<p><strong>Extensions:</strong> 12,780 plugins and 1,315 themes.</p>

<p><strong>Distinguished Clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.nytimes.com/interactive/blogs/directory.html" target="_blank">http://www.nytimes.com/interactive/blogs/directory.html</a></li>
	<li><a href="http://tmagazine.blogs.nytimes.com/" target="_blank">http://tmagazine.blogs.nytimes.com/</a></li>
	<li><a href="http://crowdfavorite.com/" target="_blank">http://crowdfavorite.com/</a></li>
	<li><a href="http://blog.broadband.gov/" target="_blank">http://blog.broadband.gov/</a></li>
	<li><a href="http://blogs.america.gov/" target="_blank">http://blogs.america.gov/</a></li>
	<li><a href="http://www.number10.gov.uk/" target="_blank">http://www.number10.gov.uk/</a></li>
	<li><a href="http://www.speaker.gov/" target="_blank">http://www.speaker.gov/</a></li>
	<li><a href="http://allthingsd.com/" target="_blank">http://allthingsd.com/</a></li>
	<li><a href="http://politicalticker.blogs.cnn.com/" target="_blank">http://politicalticker.blogs.cnn.com/</a></li>
	<li><a href="http://stylenews.peoplestylewatch.com/" target="_blank">http://stylenews.peoplestylewatch.com/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>Perhaps, the most convenient, easy to use and intuitive CMS (<em>or BMS</em>) in the world. Perfect for blog sites. But if you need to develop a dynamic site with various components, perhaps, other CMS would fit better, though, WordPress provides enough plugins to accomplish almost all tasks.</li>
	<li>I would avoid Wordpress as a CMS in a professional environment. As stated earlier, it's a great blogging platform, but doesn't generally offer the robustness that most professional environments require.</li>
	<li>Availability of jQuery makes the plugin development a lot easier for external developers and site owners.</li>
	<li>Endless themes - no need to worry about the new design for your site, unless you really need something special.</li>
</ul>
<h2>#5: DotNetNuke</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://www.dotnetnuke.com/" target="_blank"><img title="DotNetNuke" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/dotnetnuke.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site:</strong> <a href="http://www.dotnetnuke.com/" target="_blank">http://www.dotnetnuke.com/</a></p>

<p>DotNetNuke is an open source platform for building web sites based on Microsoft .NET technology. It is written in VB.NET and distributed under both a Community Edition BSD-style license <a href="http://en.wikipedia.org/wiki/DotNetNuke#cite_note-autogenerated1-2" target="_blank"></a>and a commercial proprietary license. The Community Edition is a popular web content management (WCM) system and application development framework for ASP.NET, with over 6 million downloads and 600,000 production web sites as of October 2010. More than 8,000 DotNetNuke apps are available for purchase on Snowcovered.com. DotNetNuke.com has over 800,000 registered members as of October 2010.</p>

<p><strong>Weekly downloads:</strong> 13,000 (<em>ranked #4 after Drupal and before CMS Made Simple</em>).</p>

<p><strong>Installations:</strong> 402 according to the survey (<em>#4 after Drupal and before Liferay</em>), but 0.2% of the Alexa Top 1 million sites (<em>#4 after Typo3 and before MOVABLE TYPE</em>).</p>

<p><strong>Brand Familiarity:</strong> #4 (<em>after Drupal and before Typo3</em>).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Distinguishes between community (common features) and enterprise (full set of features) editions.</li>
	<li>Various modules, and data providers.</li>
	<li>Provides language packs for about 60 languages.</li>
	<li>Customizable through skins and templates.</li>
</ul>
<strong>Distinguished&nbsp;clients:</strong><p></p>

<p></p><ul>
	<li><a href="http://www.chamberlain.edu/" target="_blank">http://www.chamberlain.edu/</a></li>
	<li><a href="http://magenic.com/" target="_blank">http://magenic.com/</a></li>
	<li><a href="http://www.graphiksolutions.ca/" target="_blank">http://www.graphiksolutions.ca/</a></li>
	<li><a href="http://www.marly.com/" target="_blank">http://www.marly.com/</a></li>
	<li><a href="http://www.dotcomsoftwaresolutions.com/" target="_blank">http://www.dotcomsoftwaresolutions.com</a></li>
	<li><a href="http://www.cityplaceascent.com/" target="_blank">http://www.cityplaceascent.com/</a></li>
	<li><a href="http://sites.kiwanis.org/kiwanis/en/home.aspx" target="_blank">http://sites.kiwanis.org/kiwanis/en/home.aspx</a></li>
	<li><a href="http://www.zonediet.com/" target="_blank">http://www.zonediet.com/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>A little bit difficult to create modules.</li>
	<li>It is perceived as a little bit bulky CMS.</li>
	<li>Does not provide extensive documentation and user guides.</li>
	<li>Similar to most CMS, does not provide full backward compatibility in its new major releases.</li>
	<li>Unlike its enterprise edition, the community edition is not tested and certified by the DotNetNuke Corporation.</li>
	<li>Even if it provides the language packs, the sites cannot be created to support multiple languages. Third party module should be used to enable this feature.</li>
	<li>Auto-upgrade, Advanced Site Search, Page Cashing, and many must-have features are not included in the Community edition, only in Professional or Enterprise editions.</li>
</ul>
<h2>#6: Umbraco</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://umbraco.org/" target="_blank"><img title="umbraco" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/umbraco.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://umbraco.org/" target="_blank">http://umbraco.org/</a></p>

<p>Umbraco is also an open source content management system. It was developed by Niels Hartvig in 2000 and released as open source software in 2004<a href="http://en.wikipedia.org/wiki/Umbraco#cite_note-history-1" target="_blank"></a>. It is written in C# and can be deployed on Microsoft based infrastructure. In 2010, with about <strong>1,000 downloads a day</strong>, Umbraco was in the Top 5 most popular downloads via the <em>Microsoft Web Platform Installer</em>, two places below its main rival DotNetNuke.</p>

<p><strong>Weekly downloads:</strong> 5,420 (<em>ranked #10 after Alfresco and before MODx</em>).</p>

<p><strong>Installations:</strong> 57 according to the survey (<em>#13 after MODx and before e107</em>), but less than 0.1% of the Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> #16 (after Liferay and before e107).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Can be deployed with several databases, including MySQL, SQL Server, and VistaDB.</li>
	<li>SEO-friendly URLs.</li>
</ul>
<strong>Extensions:</strong><span style="font-weight: normal;"> 310 add-on modules.</span><p></p>

<p><strong>What users say:</strong></p>

<p></p><ul>
	<li>Limited number of extensions.</li>
	<li>Official support for Windows OS only.</li>
	<li>Umbraco is oriented to small low-cost sites.</li>
	<li>Video trainings have to be purchased.</li>
	<li>Many must-have features have to purchased.</li>
</ul>
<h2>#7: Liferay</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://www.liferay.com/" target="_blank"><img title="Liferay" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/liferay.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://www.liferay.com/" target="_blank">http://www.liferay.com/</a></p>

<p><strong>Liferay </strong>Portal is a free and open source enterprise portal written in Java and distributed under the GNU Lesser General Public License. It allows users to set up features common to websites. It is fundamentally constructed of functional units called portlets. Liferay is sometimes described as a content management framework or a web application framework. It comes with certain portlets preinstalled. These comprise the core functionality of the portal system.</p>

<p><strong>Weekly downloads:</strong> 9,435 (<em>ranked #6 after CMS Made Simple and before TYPO3</em>).</p>

<p><strong>Installations:</strong> 154 according to the survey (<em>#5 after DotNetNuke and before TYPO3</em>), but less than 0.1% of the Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> #15 (after MODx and before Umbraco).</p>

<p><strong>Major Features/ Portlets:</strong></p>

<p></p><ul>
	<li>Can tag and categorize contents.</li>
	<li>Document Library Manager, Recent Documents.</li>
	<li>Alfresco, Documentum, and other document library integration.</li>
	<li>User management based on various roles and groups (ACL).</li>
	<li>WebDAV Integration (Web-based Distributed Authoring and Versioning which allows users to collaboratively edit and manage files on remote web servers).</li>
	<li>Nested Portlets</li>
	<li>User Directory</li>
	<li>LDAP Integration</li>
	<li>Microsoft Office Integration</li>
	<li>Calendar/Chat/Mail/Message Boards/Polls</li>
	<li>Wiki (supports Creole as well as MediaWiki syntax)</li>
	<li>Alerts and Announcements</li>
	<li>Knowledge Base</li>
	<li>Social Equity</li>
	<li>Can create multi-language sites.</li>
	<li>Asset Publisher to publish many contents, tagged by a specific term, at once.</li>
</ul>
<strong>Extensions:</strong> 27 official plugins and 208 community developed plugins.<p></p>

<p><strong>Distinguished Clients:</strong> It is primarily used to power corporate business sites.</p>

<p></p><ul>
	<li><a href="http://developer.cisco.com/" target="_blank">http://developer.cisco.com</a></li>
	<li><a href="http://www.t-mobile.cz/" target="_blank">http://www.t-mobile.cz</a></li>
	<li><a href="http://www.betavine.net/" target="_blank">http://www.betavine.net</a></li>
	<li><a href="http://www.foxchannel.de/" target="_blank">http://www.foxchannel.de/</a></li>
	<li><a href="http://www.ixarm.com/" target="_blank">http://www.ixarm.com</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>It is mostly used by enterprise companies rather than for powering personal or community sites, though it has social and collaboration features.</li>
	<li>More professional developers driven project (<em>backed by Liferay Inc.</em>) rather than the community driven.</li>
	<li>Provide paid Enterprise edition.</li>
	<li>All features are available in Community edition (<em>except for support and customization related</em>).</li>
</ul>
<h2>#8: Typo3</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://typo3.org/" target="_blank"><img title="TYPO3" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/typo3.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site:</strong> <a href="http://typo3.org/" target="_blank">http://typo3.org/</a></p>

<p><strong>TYPO3</strong> is a free and open source CMS released under the GNU General Public License oriented to small to mid size enterprise-class users. TemplaVoila is an alternative template engine extension for TYPO3. A graphical mapping tool for creating templates is included, an alternative page module, the ability to create flexible content elements and an API for developers. New content element types can be created without programming. TemplaVoila facilitates more flexibility for maintaining web pages than TYPO3's standard templating, while making it possible to enforce a strict corporate design and allowing editors to work with content more intuitively.</p>

<p><strong>Weekly downloads:</strong> 7,461 (ranked #7 after Liferay and before eZ Publish).</p>

<p><strong>Installations:</strong> 122 according to the survey (#6 after Liferay and before Tiki), 0.6% of the Alexa Top 1 million sites (#4 after Drupal and before DotNetNuke).</p>

<p><strong>Brand Familiarity:</strong> #5 (after DotNetNuke and before OpenCMS).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Supports MySQL, Oracle, MS-SQL, PostgreSQL, ODBC, LDAP - virtually any external data source.</li>
	<li>You can undo any change you make on the site.</li>
	<li>Can create multiple sites with multiple domains for each.</li>
	<li>Can have multiple template per site.</li>
	<li>User management.</li>
	<li>Able to switch from administrator user to general user to check permissions.</li>
	<li>Sandbox: administrators can set up a section within the system to test new features without disturbing the main site.</li>
	<li>Versioning of content pages.</li>
	<li>Advanced caching: template, navigation or page level.</li>
	<li>Link management.</li>
	<li>Multi-language content.</li>
	<li>Search Engine friendly URLs.</li>
</ul>
<strong>Extensions:</strong> more than 4,500 pluggable extensions are available for TYPO3.<p></p>

<p><strong>Distinguished clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.volkswagen-ir.de/" target="_blank">http://www.volkswagen-ir.de</a></li>
	<li><a href="http://www.eadssecureuk.com/" target="_blank">http://www.eadssecureuk.com</a></li>
	<li><a href="http://www.geveriwise-eu.com/" target="_blank">http://www.geveriwise-eu.com</a></li>
	<li><a href="http://www.rewe-xxl.de/" target="_blank">http://www.rewe-xxl.de</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>The administrator's UI (User Interface) is not user-friendly, though intuitive and functional.</li>
	<li>It is extremely powerful which provide more enterprise level features, but the learning curve is <em>incredibly</em> steep.</li>
	<li>Great ease of multi-lingual site management.</li>
	<li>Difficult to customize templates. Need to learn TypoScript and TemplaVoila, two TYPO3-specific systems.</li>
</ul>
<h2>#9: CMS Made Simple</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://www.cmsmadesimple.org/" target="_blank"><img title="CMS Made Simple" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/cms-made-simple.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://www.cmsmadesimple.org/" target="_blank">http://www.cmsmadesimple.org/</a></p>

<p>CMS Made Simple is an open source cms built using PHP with support for MySQL and PostgreSQL. The template system is driven using the Smarty Template Engine.</p>

<p><strong>Weekly downloads:</strong> 9,948 (ranked #5 after DotNetNuke and before Liferay).</p>

<p><strong>Installations:</strong> 72 according to the survey (#7 after Tiki and before Alfresco), 0.1% of the Alexa Top 1 million sites (#8 after Xoops and before eZ Publish).</p>

<p><strong>Brand Familiarity:</strong> #12 (after Xoop and before Ez Publish).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Officially supports MySQL and PostgreSQL.</li>
	<li>Search Engine Friendly URLs.</li>
	<li>Users management and group based permissions system.</li>
	<li>Content tagging.</li>
	<li>Site localization is available in 20 languages.</li>
</ul>
<strong>Extensions:</strong> unknown, but many.<p></p>

<p><strong>What users say:</strong></p>

<p></p><ul>
	<li>It is oriented more toward professional users.</li>
	<li>It does not provide many templates, so coding knowledge is a must.</li>
</ul>
<h2><strong>#10: Movable Type</strong></h2><p></p>

<p></p><p style="text-align: center;"><strong><a href="http://movabletype.org/" target="_blank"><img title="MOVABLETYPE" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/movabletype.png" width="701" height="325" editor_component="image_link"/></a> </strong></p><p></p>

<p><strong>Official site: </strong><a href="http://movabletype.org/" target="_blank">http://movabletype.org/</a></p>

<p><strong>Movable Type</strong> is a weblog publishing system, similar to WordPress, developed by the Six Apart company in Perl programming language. At various times, this company maintained three other publishing systems - TypePad, Vox, and LiveJournal. Movable Type was publicly announced on September 3, 2001. Version 1.0 was publicly released on October 8, 2001, thus it is a blogging system older than WordPress. On 12 December 2007, Movable Type was relicensed as free software under the GNU General Public License. Based on the list of its customers, Movable Type is quite credible CMS.</p>

<p><strong>Weekly downloads:</strong> unavailable.</p>

<p><strong>Installations:</strong> 30 according to the survey (#17 after Silverstripe and before OpenCMS), 0.1% of the Alexa Top 1 million sites (#6 after DotNetNuke and before Xoops).</p>

<p><strong>Brand Familiarity:</strong> #8 (after Plone and before Alfresco).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Convenient blogging system with social community features.</li>
	<li>Since version 5 officially supports only MySQL. PostgreSQL and SQLite can be used via plugins. Databases such as Oracle can be integrated with Movable Type Enterprise edition.</li>
	<li>Manage user roles. OpenID support.</li>
	<li>Multiple site hosting.</li>
	<li>Easily customizable templates.</li>
	<li>Revision history.</li>
	<li>Can add custom fields.</li>
	<li>Content tags and categories.</li>
	<li>Feeds and trackback links.</li>
	<li>Available localization and internationalization.</li>
	<li>Can generate static pages (updated whenever the content of the site is changed).</li>
</ul>
<strong>Extensions:</strong> about 1,000 plugins.<p></p>

<p><strong>Distinguished clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.britneyspears.com/" target="_blank">http://www.britneyspears.com/</a></li>
	<li><a href="http://www.barackobama.com/" target="_blank">http://www.barackobama.com/</a></li>
	<li><a href="http://boeingblogs.com/" target="_blank">http://boeingblogs.com/</a></li>
	<li><a href="http://blogs.oracle.com/" target="_blank">http://blogs.oracle.com/</a></li>
	<li><a href="http://gehealthcare.typepad.com/" target="_blank">http://gehealthcare.typepad.com/</a></li>
	<li><a href="http://www.spd.org/" target="_blank">http://www.spd.org/</a></li>
	<li><a href="http://blog.ted.com/" target="_blank">http://blog.ted.com/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>Users often deploy Movable Type for their blog sites, newspaper or other type of publishing sites.</li>
	<li>A powerful alternative for WordPress.</li>
</ul>
<h2>#11: Plone</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://plone.org/" target="_blank"><img title="Plone" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/plone.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://plone.org/" target="_blank">http://plone.org/</a></p>

<p><strong>Plone</strong>, a free and open source CMS, started in 1999 by Alexander Limi, Alan Runyan, and Vidar Andersen. It was made as a usability layer on top of the Zope content management framework, thus Plone is written in Python. The first version was released in 2001. In 2004, Plone 2.0 was released. This release brought more customizable features to Plone, and enhanced the add-on functions. In 2007, Plone 3 was released. This new release brought inline editing, an upgraded visual editor, and strengthened security, among many other enhancements. Recently in 2010, Plone 4 was released with major improvements in performance.</p>

<p><strong>Weekly downloads:</strong> unavailabe.</p>

<p><strong>Installations:</strong> 34 according to the survey (#15 after e107 and before Silverstripe), 0.1% of the Alexa Top 1 million sites (#10 after eZ Publish).</p>

<p><strong>Brand Familiarity:</strong> #7 (after OpenCMS and before Movable Type).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Inline editing - no need to reload the page for editing.</li>
	<li>Localized into 40 languages.</li>
	<li>Plone can be integrated with Active Directory, Salesforce, LDAP, SQL, Web Services, and Oracle.</li>
	<li>Working Copy support - keep the old version of a content published until you publish a new version.</li>
	<li>Cut/copy/paste operations on content.</li>
	<li>Link and reference integrity checking - no more broken links within your site.</li>
	<li>Can create workflows - useful for organizations.</li>
	<li>LiveSearch - instant site search powered by AJAX.</li>
	<li>Full-text indexing of Word and PDF documents.</li>
	<li>Wiki support</li>
	<li>Collaboration and sharing</li>
	<li>Automatic locking and unlocking</li>
	<li>Versioning, history and reverting content</li>
	<li>Authentication back-end</li>
	<li>Collections</li>
	<li>Multilingual content management</li>
	<li>Automatic previous/next navigation</li>
	<li>Human-readable URLs</li>
	<li>Caching proxy integration</li>
	<li>Drag and drop reordering of content</li>
	<li>Adjustable templates on content</li>
	<li>RSS feed support</li>
	<li>Automatic image scaling and thumbnail generation</li>
	<li>Comment capabilities on any content</li>
	<li>WebDAV and FTP support</li>
	<li>Hot -backup support</li>
</ul>
<strong>Extensions:</strong> 1490 add-ons.<p></p>

<p><strong>Distinguished clients:</strong></p>

<p></p><ul>
	<li><a href="http://www.amnesty.ch/en" target="_blank">http://www.amnesty.ch/en</a></li>
	<li><a href="http://www.brasil.gov.br/" target="_blank">http://www.brasil.gov.br/</a></li>
	<li><a href="http://www.chicagohistory.org/" target="_blank">http://www.chicagohistory.org/</a></li>
	<li><a href="http://ccnmtl.columbia.edu/" target="_blank">http://ccnmtl.columbia.edu/</a></li>
	<li><a href="http://cnx.org/" target="_blank">http://cnx.org/</a></li>
	<li><a href="http://discovermagazine.com/" target="_blank">http://discovermagazine.com/</a></li>
	<li><a href="http://www.ece.rice.edu/" target="_blank">http://www.ece.rice.edu/</a></li>
	<li><a href="http://www.engagemedia.org/" target="_blank">http://www.engagemedia.org/</a></li>
	<li><a href="http://science.nasa.gov/" target="_blank">http://science.nasa.gov/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>It has a lot of features (<em>several times more than listed above</em>) built-in.</li>
	<li>To become a Plone expert is long and expensive. It has a steep learning curve.</li>
	<li>Plone is backed by Zope framework which is very powerful with support for caching, rollback, etc. - everything what your organization might need.</li>
	<li>Plone is really complex to deeply tweak.</li>
	<li>Plone is known for its high security.</li>
	<li>Plone runs slow if you don't know how to optimize it.</li>
</ul>
<h2>#12: eZ Publish</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://ez.no/" target="_blank"><img title="eZ Publish" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/ez.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://ez.no/" target="_blank">http://ez.no/</a></p>

<p>eZ Publish is an open source enterprise CMS developed by the Norwegian company eZ Systems in 1999 using PHP programming language. eZ Publish is freely available under the GPL licence, as well as under proprietary licenses that include commercial support. eZ Publish supports the development of customized web applications. Typical applications range from a personal homepage to a multilingual corporate website, which include role-based multi-user access, e-commerce functions and online communities.</p>

<p><strong>Weekly downloads:</strong> 7,031 (ranked #8 after TYPO3 and before Alfresco).</p>

<p><strong>Installations:</strong> 60 according to the survey (#11 after Concrete5 and before MODx), 0.1% of the Alexa Top 1 million sites (#9 after CMS Made Simple and before Plone).</p>

<p><strong>Brand Familiarity:</strong> #13 (after CMS Made Simple and before MODx).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Advanced Search feature is available in only Enterprise Edition.</li>
	<li>Online image editor.</li>
	<li>Can create building blocks for the site and later reuse them in several pages.</li>
</ul>
<strong>Distinguished clients:</strong><p></p>

<p></p><ul>
	<li><a href="http://www.schemexpert.com/" target="_blank">http://www.schemexpert.com/</a></li>
	<li><a href="http://www.ticotimes.net/" target="_blank">http://www.ticotimes.net/</a></li>
	<li><a href="http://jp.wsj.com/" target="_blank">http://jp.wsj.com/</a></li>
	<li><a href="http://www.laborange.fr/" target="_blank">http://www.laborange.fr/</a></li>
	<li><a href="http://canalstreet.canalplus.fr/" target="_blank">http://canalstreet.canalplus.fr/</a></li>
	<li><a href="http://www.hks.harvard.edu/" target="_blank">http://www.hks.harvard.edu/</a></li>
	<li><a href="http://www.vogue.com.au/" target="_blank">http://www.vogue.com.au/</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>The documentation is a bit limited especially there is almost no documentation for module development.</li>
</ul>
<h2>#13: Concrete 5</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://www.concrete5.org/" target="_blank"><img title="concrete5" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/concrete5.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://www.concrete5.org/" target="_blank">http://www.concrete5.org/</a></p>

<p><strong>Concrete5</strong> is an open source CMS started in 2003 as a rapid-design approach to building the now-defunct LewisAndClark200.org, the official site for the Ad Council's National Council for the Lewis &amp; Clark Bicentennial. Concrete5 is developed in PHP and is distributed under MIT software license.</p>

<p><strong>Weekly downloads:</strong> unavailable.</p>

<p><strong>Installations:</strong> 62 according to the survey (#10 after Alfresco and before eZ Publish), has less than 0.1% of the Alexa Top 1 million sites.</p>

<p><strong>Brand Familiarity:</strong> #20 (after TextPattern).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Integrated server side caching.</li>
	<li>Support for only MySQL.</li>
	<li>Inline content editing.</li>
	<li>Image editing tool.</li>
	<li>Editable areas are defined in concrete5 templates which allow editors to insert 'blocks' of content. Additional blocks are available as add-ons.</li>
	<li>Automatic upgrade is available.</li>
	<li>Advanced Permissions to track content versions.</li>
</ul>
<strong>Distinguished clients:</strong><p></p>

<p></p><ul>
	<li><a href="http://www.genco.com/" target="_blank">http://www.genco.com</a></li>
	<li><a href="http://www.cottonfrombluetogreen.org/" target="_blank">http://www.cottonfrombluetogreen.org/</a></li>
	<li><a href="http://www.cs.uh.edu/" target="_blank">http://www.cs.uh.edu/</a></li>
	<li><a href="http://www.signals.ca/" target="_blank">http://www.signals.ca/</a></li>
	<li><a href="http://www.paulraymondgregory.com/" target="_blank">http://www.paulraymondgregory.com</a></li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>It's PHP based and quite new but it's quite a nice layout and it's really natural for new CMS users. You can go from a paper-based sitemap and PSD to a full site structure, ready for data entry, within a day, two at a push.</li>
	<li>Concrete5 is simple, suitable for creating sites quickly.</li>
	<li>Creating template is very easy with Concrete5.</li>
</ul>
<h2>#14: Alfresco</h2><p></p>

<p></p><p style="text-align: center;"><a href="http://www.alfresco.com/" target="_blank"><img title="Alfresco" src="http://blog.cubrid.org/wp-content/uploads/2011/1-/alfresco.png" width="701" height="325" editor_component="image_link"/></a></p><p></p>

<p><strong>Official site: </strong><a href="http://www.alfresco.com/" target="_blank">http://www.alfresco.com/</a></p>

<p><strong>Alfresco</strong> is an open source enterprise content management system for Microsoft Windows and Unix-like operating systems. Alfresco includes a content repository, an out-of-the-box web portal framework for managing and using standard portal content, a CIFS interface that provides file system compatibility on Microsoft Windows and Unix-like operating systems, a web content management system capable of virtualizing web apps and static sites via Apache Tomcat, Lucene indexing, and jBPM workflow. The Alfresco system is developed using Java technology. John Newton (co-founder of Documentum) and John Powell (a former COO of Business Objects) founded Alfresco Software, Inc. in 2005.</p>

<p><strong>Weekly downloads:</strong> 7,000 (ranked #9 after Ez Publish and before Umbraco).</p>

<p><strong>Installations:</strong> 70 according to the survey (#9 after CMS Made Simple and before Concrete5) Alexa ranking is not available.</p>

<p><strong>Brand Familiarity:</strong> #9 (after Movable Type and before Tiki).</p>

<p><strong>Major Features:</strong></p>

<p></p><ul>
	<li>Document Management.</li>
	<li>Web Content Management (including full webapp &amp; session virtualization).</li>
	<li>Repository-level versioning (similar to Subversion).</li>
	<li>Records Management, including 5015.2 certification.</li>
	<li>Repository access via CIFS /SMB, FTP, Web DAV, NFS and CMIS.</li>
	<li>j BPM workflow.</li>
	<li><a title="Lucene" href="http://en.wikipedia.org/wiki/Lucene" target="_blank"></a>Advanced search with Lucene.</li>
	<li>Multi-language support.</li>
	<li>Officially runs on Windows, Linux and Solaris.</li>
	<li>User Interface official supports Internet Explorer and Firefox.</li>
	<li>Desktop integration with Microsoft Office and OpenOffice.org.</li>
	<li>Clustering support.</li>
	<li>Pluggable authentication: NTLM, LDAP, Kerberos, CAS.</li>
</ul>
<strong>Distinguished clients:</strong> no links are available but numerous case studies can be found on Alfresco home page.<p></p>

<p></p><ul>
	<li>France Air Force</li>
	<li>Harvard Business School Publishing</li>
	<li>Toyota</li>
	<li>Sony Pictures</li>
	<li>Fox</li>
	<li>National Academy of Sciences</li>
	<li>Cisco</li>
</ul>
<strong>What users say:</strong><p></p>

<p></p><ul>
	<li>Alfresco is mostly for enterprises rather than for personal sites.</li>
	<li>Simple to install and use, flexible and open-ended.</li>
	<li>Alfresco is a solution with the broadest range of technical capabilities and the best feedback from users. In addition to demonstrating a promising roadmap for collaboration tools, Alfresco was highly attractive from a cost perspective, compared to the proprietary products offered by other ECM vendors.</li>
	<li>All in one solution for enterprises.</li>
</ul>
<h2>See also</h2><p></p>

<p>Besides, the official home pages, you can refer to Wikipedia for&nbsp;general information on these content management systems. Also <a title="Stack Overflow" href="http://stackoverflow.com/" target="_blank">Stack Overflow</a> provides very informative users feedbacks on each of these CMS.</p>

<p></p><ol>
	<li><a href="http://en.wikipedia.org/wiki/Drupal" target="_blank">http://en.wikipedia.org/wiki/Drupal</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Joomla" target="_blank">http://en.wikipedia.org/wiki/Joomla</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Modx" target="_blank">http://en.wikipedia.org/wiki/Modx</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Wordpress" target="_blank">http://en.wikipedia.org/wiki/Wordpress</a></li>
	<li><a href="http://en.wikipedia.org/wiki/DotNetNuke" target="_blank">http://en.wikipedia.org/wiki/DotNetNuke</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Umbraco" target="_blank">http://en.wikipedia.org/wiki/Umbraco</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Liferay" target="_blank">http://en.wikipedia.org/wiki/Liferay</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Typo3" target="_blank">http://en.wikipedia.org/wiki/Typo3</a></li>
	<li><a href="http://en.wikipedia.org/wiki/CMS_Made_Simple" target="_blank">http://en.wikipedia.org/wiki/CMS_Made_Simple</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Movable_Type" target="_blank">http://en.wikipedia.org/wiki/Movable_Type</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Plone_(software" target="_blank">http://en.wikipedia.org/wiki/Plone_(software)</a></li>
	<li><a href="http://en.wikipedia.org/wiki/EZ_Publish" target="_blank">http://en.wikipedia.org/wiki/EZ_Publish</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Concrete5" target="_blank">http://en.wikipedia.org/wiki/Concrete5</a></li>
	<li><a href="http://en.wikipedia.org/wiki/Alfresco_(software" target="_blank">http://en.wikipedia.org/wiki/Alfresco_(software)</a></li>
	<li><a title="OPEN SOURCE CMS MARKET SHARE REPORT" href="http://www.waterandstone.com/sites/default/files/2010 OSCMS Report.pdf" target="_blank">http://www.waterandstone.com/sites/default/files/2010%20OSCMS%20Report.pdf</a></li>
	<li><a href="http://php.opensourcecms.com/" target="_blank">http://php.opensourcecms.com/</a></li>
	<li><a href="http://stackoverflow.com/" target="_blank">http://stackoverflow.com/</a></li>
</ol><p></p>]]></description>
                        <pubDate>Fri, 21 Jan 2011 11:22:43 +0900</pubDate>
                        <category>Wordpress</category>
                        <category>Joomla</category>
                        <category>CMS</category>
                        <category>content management system</category>
                        <category>Web 2.0</category>
                        <category>Drupal</category>
                        <category>Concrete5</category>
                        <category>MODx</category>
                        <category>DotNetNuke</category>
                        <category>Liferay</category>
                        <category>TYPO3</category>
                        <category>CMS Made Simple</category>
                        <category>MOVABLE TYPE</category>
                        <category>Plone</category>
                        <category>eZ Publish</category>
                        <category>Alfresco</category>
                        <category>Umbraco</category>
                                    <slash:comments>8</slash:comments>
                    </item>
        										        <item>
            <title>Best PHP IDE to work with CUBRID Database</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-appstools/best-php-ide-phpstorm-now-supports-cubrid-api-syntax/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-appstools/best-php-ide-phpstorm-now-supports-cubrid-api-syntax/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-appstools/best-php-ide-phpstorm-now-supports-cubrid-api-syntax/#comment</comments>
                                    <description><![CDATA[<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/114/353/phpstorm_logo.png" alt="PHPStorm Logo" width="300" height="68" editor_component="image_link" /></p>

<p>When developers review various IDE for PHP, it is not accident that&nbsp;<a href="http://www.jetbrains.com/phpstorm" target="_self">PHPStorm</a>&nbsp;is among the top ranked. Because it is one of the best feature-rich PHP&nbsp;Development Tools out there. The good news is JetBrains, the company behind this project, has just released a new version of PHPStorm 4.0.&nbsp;If you try PHPStorm 4.0, I bet you won't wish to come back to your current IDE. It's really the smartest PHP IDE I have ever used!</p>

<p>I am sure there are still&nbsp;many geeks who use Notepad++ or TextMate to write their code.&nbsp;I had personally used Notepad++ for over 6 years. It is great for source code editing. It is small and fast. But when it comes to working&nbsp;in a team&nbsp;on a large project, control the version of the code, commit, push to, or auto sync with the remote stage server which is accessible only through SSH, merge the remote changes, and all this with a press of a keyboard shortcut, you need a fully fledged IDE which will help you accomplish all these effortlessly. And PHPStorm is that IDE which lets you focus on creating the beautiful code and leave the rest to the IDE.</p><p>I won't enumerate <a href="http://www.jetbrains.com/phpstorm/features/index.html" target="_self">all the features</a>&nbsp;available in PHPStorm in this blog, but I want to tell you only about my favorite ones.</p><h2>Intelligent PHP Editor</h2><h3></h3><h3>Auto completion</h3><p>It is not just the usual code completion or syntax highlighting features which are available in almost all source code editors and IDEs. In addition to that PHPStorm shows auto complete suggestions for array indexes within your PHP code. This is very convenient!</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/code_completion.png" alt="code_completion.png" width="291" height="106" editor_component="image_link" /></p><p>What I like even more is how easy it is to&nbsp;<i><b>replace</b></i>&nbsp;the code by another code suggested by PHPStorm. Assume you have accidentally typed <span style="font-family: monospace; ">cubrid_close()</span> instead of <span style="font-family: monospace; ">cubrid_connect()</span>.</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/auto_complete_example.png" alt="auto_complete_example.png" width="166" height="48" editor_component="image_link" /><br /></p><p>Instead of manually pressing several times on <i>Backspace/Delete</i>&nbsp;key on your keyboard to delete the "<span style="font-family: monospace; ">close()</span>" part of the function, all you have to do is to place the cursor after the underscore, start typing your desired function, then press <i>Tab</i>&nbsp;key&nbsp;on your keyboard. This will automatically replace the rest of the word with the one selected in the auto complete list. I like this feature very much! It saves so much time!</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/auto_complete_replace.png" alt="auto_complete_replace.png" width="461" height="90" editor_component="image_link" /><br /></p>

<h3>Support for CUBRID PHP API syntax</h3><p>PHPStorm is the first IDE to provide code completion for&nbsp;<a href="http://php.net/manual/en/book.cubrid.php" target="_self">CUBRID PHP API</a>. I would give the credit to them just for this feature!</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/phpstorm-cubrid-php-syntax-autocompletion.png" alt="phpstorm-cubrid-php-syntax-autocompletion.png" width="508" height="218" editor_component="image_link" /><br /></p><p>It is not just the code completion, but also the entire documentation of the selected API is available on keyboard shortcut (<b>Ctrl+J</b>).</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/phpstorm-cubrid-php-api-syntax-support.png" alt="phpstorm-cubrid-php-api-syntax-support.png" width="793" height="493" editor_component="image_link" /></p>

<h2>Code quality analysis</h2>

<h3>Support for PHP Code Sniffer</h3><p>PHPStorm has really valuable features to improve the quality of your PHP code. Its on-the-fly error checking allows you to detect coding standard violations using popular&nbsp;<a href="http://pear.php.net/package/PHP_CodeSniffer" target="_self">PHP Code Sniffer</a>. Also, it provides PEAR, Zend as well as Drupal coding style support as well as various techniques for code refactoring. It is just perfect for PHP coding.</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/sniffer.png" alt="sniffer.png" width="430" height="160" editor_component="image_link" /><br /></p>

<h3>Integrated PHPUnit</h3><p>It is so easy in PHPStorm to write test cases and run them with PHPUnit. It is even more pleasant to instantly see how much of your code is covered by the tests. It helps you immediately spot where you have to fill the gaps.</p><p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/coverage_screenshot1.png" alt="coverage_screenshot1.png" width="430" height="230" editor_component="image_link" /><br /></p><h3>Visual PHP debugger</h3><p>PHP debugging in PHPStorm is very easy. In fact you need zero configuration to have it working. Once you install your favorite debugger (I personally use <a href="http://xdebug.org/" target="_self">Xdebug</a>; Zend Debugger is also supported), it is ready to go. You can debug both local and remote servers. The debugging session is kept alive while you move between web pages. If you have difficulties configuring the debugger, there is a <a href="http://blog.jetbrains.com/webide/2011/03/configure-php-debugging-in-phpstorm-2-0/" target="_self">step by step tutorial</a>&nbsp;and even a <a href="http://www.jetbrains.com/phpstorm/demos/remote_debugging/remote_debugging.html" target="_self">video tutorial</a>.</p>

<h2>Powerful set of keyboard bindings</h2>

<p><img src="http://www.cubrid.org/files/attach/images/220547/114/353/shortcuts.png" alt="shortcuts.png" width="495" height="229" editor_component="image_link" /><br /></p><p>This is perhaps the best thing in PHPStorm. There are so many predefined <a href="http://www.jetbrains.com/phpstorm/documentation/PhpStorm_ReferenceCard.pdf" target="_self">keyboard shortcuts</a> in PHPStorm that you can accomplish almost anything instantly with just your keyboard be it code committing or pushing, adding or deleting a file from your local repository, uploading a file to the remote server via SFTP or FTP, syncing with the remote VCS repository (I personally use Git, but it also supports SVN, Mercury, CVS, TFS, and Perforce). Various server side operations can be triggered by a mere shortcut.</p><p>My most favorite shortcut is <span style="font-family: monospace; ">Ctrl+Cmd+↑</span>&nbsp;to upload the currently active file to the remote stage server via SFTP so that I can see the changes live on the development server. It is especially convenient when you do not have the full test server on your local machine. By the way, you will not find this shortcut in PHPStorm because I have set it for myself. In PHPStorm you can assign your own shortcut to any available action. For this go to&nbsp;<span style="font-family: monospace; ">Settings &gt; Keymap</span>. In my case I have assigned the above shortcut for <span style="font-family: monospace; ">Settings &gt; Keymap &gt; Plugins &gt; Remote Hosts Access &gt; Upload to Default server</span>. Super convenient!</p><h2>Full support for PHP 5.4</h2><p>The latest version of PHPStorm has full support for PHP 5.4 including traits, class member access on instantiation, short array syntax, array dereferencing on function call, binary literals, expressions in static calls, etc. If you want to develop for PHP 5.4, PHPStorm will make it very easy! It is just perfect for&nbsp;PHP reliant Web applications development.</p><p></p><h2>Frequent updates</h2><p>Last but not least, I like how frequently PHPStorm gets patches. Once in a while it pops up a message window asking you to update the IDE. The updates are available immediately on all supported operating systems&nbsp;(Windows, Mac OS X, Linux). You сan feel how the developers are trying to make their product better.</p><h2>But...</h2><p>I should say that there is one BUT, maybe the BIG one. PHPStorm is a commercial IDE (99 USD). For some this may be the important criteria when choosing the code editor. But I will tell you what! Try it (free trial for 30 days)! You will really love it! They also provide free licenses to open source projects (our team is using PHPStorm under the open source license) as well as to educational institutions. So if you are an official member of an open source project, requests your free license and enjoy coding!</p>]]></description>
                        <pubDate>Tue, 15 May 2012 15:34:30 +0900</pubDate>
                        <category>PHPStorm</category>
                        <category>PHP</category>
                        <category>IDE</category>
                        <category>programming</category>
                        <category>CUBRID Affiliates</category>
                                </item>
        										        <item>
            <title>SIDU - incredibly Simple &amp; Intuitive Web based SQL Client</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-appstools/sidu-incredibly-simple-intuitive-web-based-sql-client/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-appstools/sidu-incredibly-simple-intuitive-web-based-sql-client/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-appstools/sidu-incredibly-simple-intuitive-web-based-sql-client/#comment</comments>
                                    <description><![CDATA[<p style="text-align: center;"><b><img src="http://www.cubrid.org/files/attach/images/194381/836/354/sidu_table_select.png" width="500" height="348" editor_component="image_link" /></b></p><p><b>What do Web developers need from an SQL Client?</b>&nbsp;An easy, uncluttered Web interface to&nbsp;execute and obtain the results for the most basic SQL queries: <span style="font-family: monospace; ">SELECT</span>, <span style="font-family: monospace; ">INSERT</span>, <span style="font-family: monospace; ">DELETE</span>, <span style="font-family: monospace; ">UPDATE</span> (SIDU). This is exactly what <a href="/wiki_apps/entry/sidu-select-insert-delete-update-web-sql-client" target="_self">SIDU</a>&nbsp;does and&nbsp;stands for! Even better - SIDU does not require any installation or configuration. Just extract the files into a directory accessible by your Web server, then open your browser. Done!</p><p>Written in PHP, SIDU is really the simplest and most intuitive Web based SQL Client I have ever used. The great news is that the latest version of SIDU 3.5 now <a href="http://sidu.sourceforge.net/sidu/sidu-history.php" target="_self">officially</a> supports CUBRID Database. At CUBRID, we are very excited about this because when we have tried the beta version of SIDU 3.5 we have fallen in love with it! If you try it, you will understand how simplicity and attention to small details make so much impression on a user.</p><p>Here is what SIDU has to offer:</p>

<ul><li>CRUD operations with CUBRID, MySQL, PostgreSQL, and SQLite databases.</li><li>No need to install or configure. Just extract and open the browser.</li><li>Minimalistic app (<i>210KB</i>). Provides only what it is designed for: SIDU (SELECT, INSERT, DELETE, UPDATE).</li><li>Simultaneously connect to multiple databases.</li><li>Database and table navigation panel.</li><li>Multiple query execution. Displays query results for all statements.</li><li>Provides SHOW CREATE TABLE.</li><li>Keeps SQL execution history.</li><li>Useful keyboard shortcuts.</li><li>Built-in <b>filter</b>&nbsp;in the query results panel. No need to change the main query.</li><li>Hide unnecessary columns in the query results panel.</li></ul>

<p>So, if you need an instant access to your database from Web to quickly execute SQL, SIDU is the app you are looking for!&nbsp;We have created a short&nbsp;<a href="/wiki_apps/entry/sidu-cubrid-tutorial" target="_self">tutorial with screenshots</a>&nbsp;to illustrate SIDU in action. Check it and see how easy it is to execute SQL in your browser with SIDU.</p><p>


</p>
<blockquote class="q4"><p style="text-align: center;"><b>Information for our readers!</b></p><p style="text-align: center;"><b>If you develop an open source application</b> and would like to become a <b>CUBRID Partner</b> by supporting CUBRID Database in your project, contact us by email <a href="mailto:affiliates@cubrid.org" target="_self">affiliates@cubrid.org</a>. In your letter please provide an overview of your software, project links, and your statement on behalf of your project. We will be very glad to have you onboard!</p></blockquote>]]></description>
                        <pubDate>Tue, 08 May 2012 11:25:28 +0900</pubDate>
                        <category>CUBRID Affiliates</category>
                        <category>SIDU</category>
                        <category>SQL</category>
                        <category>SQL Client</category>
                        <category>Web App</category>
                        <category>CUBRID Manager</category>
                                </item>
        										        <item>
            <title>CUBRID Will Power 2014 Asian Games Website</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/news/cubrid-will-power-2014-asian-games-website/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/news/cubrid-will-power-2014-asian-games-website/</guid>
                        <comments>http://www.cubrid.org/blog/news/cubrid-will-power-2014-asian-games-website/#comment</comments>
                                    <description><![CDATA[<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/859/221/17th_asia_games.png" alt="2014 17th Asian Games" width="200" height="209" editor_component="image_link"/><br /></p><p>Hello everybody!</p>

<p>I am very pleased to announce this great, really great news! Last week&nbsp;on March 18, 2011, <a title="CUBRID - Open Source Database Management System Optimized for Web" href="http://www.cubrid.org">CUBRID RDBMS</a> was chosen to power the Official Web Site of the <strong>17th Asian Games</strong> which will be held in 2014&nbsp;in Incheon, South Korea.</p>

<p>The event officials say: "Considering the total cost of ownership of existing foreign database management systems, we think it is better to adopt the Korean DBMS which provides many features. This is going to be an impressive wave of about&nbsp;4 billion Asians who are expected to communicate through the event homepage."</p>

<p>The event will last 18 days, and at this moment the Organizers have already started the preparations. They are developing a comprehensive plan which will guarantee the success of the event. Besides the Official Web Site, the Organizing Committee is planning to heavily use Social Networking Services to promote the new media.</p>

<a name="more"></a>

<p>It is both very impressive and very challenging for CUBRID to be the database management system for world events. I hope one day CUBRID will be deployed as part of IT systems for even bigger events such as 2012 London Olympics.</p><p>For more information about the 2014 Asian Games refer to the Wikipedia article at <a href="http://en.wikipedia.org/wiki/2014_Asian_Games">http://en.wikipedia.org/wiki/2014_Asian_Games</a>.</p>

<div id="endic_ext_wrapper" style="display: none; "></div>]]></description>
                        <pubDate>Wed, 23 Mar 2011 08:23:34 +0900</pubDate>
                        <category>News</category>
                        <category>CUBRID</category>
                        <category>2014 Asian Games</category>
                                </item>
        										        <item>
            <title>Android, at a glance</title>
            <dc:creator>Dong Ho Han</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/android-at-a-glance/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/android-at-a-glance/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/android-at-a-glance/#comment</comments>
                                    <description><![CDATA[<p style="TEXT-ALIGN: center"><a href="http://blog.cubrid.org/wp-content/uploads/2011/09/android-logo.png"><img title="Android" src="http://blog.cubrid.org/wp-content/uploads/2011/09/android-logo.png" width="170" height="200" editor_component="image_link"/></a></p>
<p>Android, currently the most popular mobile operating system in the world, continues to further solidify its position as the major mobile platform i the world. In this article I will briefly cover how Android has appeared, and will explain its software structure and what has to be paid attention when developing apps for this platform.</p>
<h2>What is Android?</h2>
<p>Linux operating system is the main component in Android's software stack. It does not differ much from Microsoft's Windows OS or Apple's Mac OS which we use on the daily basis. Therefore, theoretically you can enjoy Android not only on mobile devices but also on other tablet devices as well just like Windows even to a point where various applications can be downloaded and used. Of course, if you want to make an Android application by yourself, you should also install ADK (Android Development Kit) to your PC and use Java programming language for development. For a lower level program, NDK (Native Development Kit) for C language shall be used.</p>
<p>It seemed that Android had been shunned publicly for not having as sensitive UI as iPhone. However, now it is considered as the most viable blue-chip mobile OS with advantageous openness, free, and Java-based characteristics.</p>
<p>Another interesting aspect is that most users mistakenly think that Android was developed by Google. In fact, it was developed in 2003 by "Android" company based in California. Back then, few people knew about it, even less developed for it. However, everything was changed in 2005 when Google acquired Android company to give birth to Android that we know now.</p><a name="more"></a>
<h2>The History of Google Android</h2>
<p>Since its initial release of 1.0 version in September 23<sup>rd</sup>, 2008, Android has enjoyed a remarkable growth. All versions until 3.0 (code name <em><strong>Honeycomb</strong></em>) are available under Apache free open source license. According to<a title="I think I’m having a Gene Amdahl moment" href="http://android-developers.blogspot.com/2011/04/i-think-im-having-gene-amdahl-moment.html">Android official blog</a>, the source code of the Honeycomb series was not released to the public because it was specifically created for tablet computers, and Google did not want external developers to mess up the user interface by putting on smartphones a version of Android intended for tablets.</p>
<p>However, Google later <a title="From I/O 2011 – Confirmed: Honeycomb source will never exist on its own" href="http://www.geek.com/articles/mobile/from-io-2011-confirmed-honeycomb-source-will-never-exist-on-its-own-20110510/">announced</a> that in the next 4.0 version, planned for the second half of this year (code name<strong><em>Ice Cream Sandwitch</em></strong>), Android will combine both the smartphone version (code name <em><strong>Gingerbread</strong></em>) and the tablet version (<em><strong>HoneyComb</strong></em>).</p>
<p>The first version of Android, released back in 2008, had drawbacks in many aspects. Some users voiced their worries about its terrible UI and development tools, saying “who would want to use it”. However with its advantage of using Java as SDK language and its openness Android gradually solidified itself as the most rapidly developing mobile OS, and it seems as if no one dare to challenge the idea that Android will further expand and attract more users than iPhone and be loaded onto more various mobile devices.</p>
<p>The following are the key functions of each Android version</p>
<ul>
<li>2.0, 2.1 (<em><strong>Eclair</strong></em>): Web browser supporting new UI and HTML5. Advanced camera app, new launcher app and weather app. Supports moving background.</li>
<li>2.2 (<em><strong>Froyo</strong></em>) : Improved performance by optimizing JIT. Chrome V8 Javascript engine. Support Wi-fi hot spot tethering and Flash.</li>
<li>2.3 (<em><strong>Gingerbread</strong></em>) : Optimized UI for minimum battery use. Enhanced soft keyboard, COPY/PASTE function, NFC (Near Field Communication, local network).</li>
<li>3.0 (<em><strong>Honeycomb</strong></em>) : Support tablet screen. New UI and multi-core processor.</li>
<li>3.2 (<em><strong>Honeycomb</strong></em>) : Compatible mode for zoom-to-fill screen. Read media file directly from SD card. Additional screen API. Controls UI more delicately.</li>
<li>4.0 (<em><strong>Ice Cream Sandwich</strong></em>) : Combined version of <em>Gingerbread</em> and Honeycomb.</li></ul>
<h2>The Structure of Android</h2>
<p>Android basically runs on <strong>DVM</strong> (Dalvik Virtual Machine) which is Android runtime loaded on Linux kernel. The figure below illustrates all the components. Further I will explain each of them from top to down.</p>
<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/480/224/typical-schematic-of-android_structure.png" alt="typical-schematic-of-android_structure.png" width="660" height="512" editor_component="image_link"/><br /></p>
<p style="text-align:center"><b><br /></b></p><p style="text-align:center"><b><br /></b></p><p style="text-align:center"><b><br /></b></p><p style="text-align:center"><b>ANDROID STRUCTURE</b></p>
<h3>Applications</h3>
<p>This domain is for applications developed with Java. Generally, email client, SMS program, calendar, browser and contacts applications are loaded.</p>
<h3>Application Framework</h3>
<p>Application framework provides all kinds of APIs needed to develop a full-featured application for Android platform. Using APIs in this domain allows to express buttons and text on the screen or use data of other applications such as images and character strings. Also it is possible to manage application’s lifecycle.</p>
<h3>Libraries</h3>
<p>This domain provides various C/C++ libraries which can be used on Android. All libraries in this domain can be used by developers via application framework. <em>Standard C system libraries</em> based on BSD (Berkeley Software Distribution) are revised to be suitable for Linux-based devices. <em>Media library</em> based on OpenCore of PacketVideo supports MPEG4, H.264, MP3, AAC, AMR, JPG and PNG files. <em>Surface manager</em> supports 2D and 3D graphics while<em>WebKit</em> supports browser functions. <em>SQLite</em> is also available as a database engine which can be used by applications.</p>
<h3>Android Runtime</h3>
<p>Although Android is developed in Java language, DVM (Dalvik Virtual Machine) is used instead of JVM (Java Virtual Machine). Thus, a source code (Java) is compiled to a class file (.class) with Java compiler which is later transformed to Dalvik Executable by DX tools. The reason for this is that Dalvik is optimized to run on small sized devices with limited memory.</p>
<h3>Linux Kernel</h3>
<p>Android is developed based on Linux kernel 2.6 which provides high security, memory and process management, network stack and various drivers.</p>
<h2>Android Project Structure</h2>
<p>Android applications are developed in Java. However, unlike the desktop version of Java applications, the class files in Android applications are not loaded directly. Instead Android's development tools combine the resource files and DEX file transformed from class file to make APK. And this APK gets loaded.</p>
<p>Below is the basic directory structure for developing the Android application.</p>
<table class="blackcap rowbg">
<tbody>
<tr>
<td valign="top" width="209">/assets</td>
<td valign="top" width="305">Data files to be installed to device along with the application.</td></tr>
<tr>
<td valign="top" width="209">/bin</td>
<td valign="top" width="305">Compiled application file.</td></tr>
<tr>
<td valign="top" width="209">/gen</td>
<td valign="top" width="305">Resource reference files automatically created by the Android build system.</td></tr>
<tr>
<td valign="top" width="209">/res</td>
<td valign="top" width="305">Resource files such as character strings and images to be used in the application.</td></tr>
<tr>
<td valign="top" width="209">/src</td>
<td valign="top" width="305">Application source code.</td></tr>
<tr>
<td valign="top" width="209">AndroidManifest.xml</td>
<td valign="top" width="305">Basic set file of application.</td></tr></tbody></table>
<p>You need to make sure that files are stored in the right directory, particularly for resources. Since directories are already reserved, changing at your will would make directories difficult to recognize.</p>
<h3>Resource Directory</h3>
<p>Resource directory is composed of <strong>drawable directory</strong> for placing images and <strong>layout directory</strong> for putting the XML files to the layout. <strong>Raw</strong> and <strong>xml</strong> directories are not automatically created in the default project, so should be created manually.</p>
<table class="blackcap rowbg">
<tbody>
<tr>
<td width="157">/res/drawable-hdpi</td>
<td width="238">Image to be shown on hdpi.</td></tr>
<tr>
<td width="157">/res/drawable-ldpi</td>
<td width="238">Image to be shown on ldpi.</td></tr>
<tr>
<td width="157">/res/drawable-mdpi</td>
<td width="238">Image to be shown on mdpi.</td></tr>
<tr>
<td width="157">/res/drawable-nodpi</td>
<td width="238">Image to be shown regardless of density.</td></tr>
<tr>
<td width="157">/res/layout/</td>
<td width="238">XML file defining UI layout.</td></tr>
<tr>
<td width="157">/res/layout-port/</td>
<td width="238">XML file defining UI layout (vertical mode).</td></tr>
<tr>
<td width="157">/res/layout-land/</td>
<td width="238">XML file defining UI layout (horizontal mode).</td></tr>
<tr>
<td width="157">/res/menu/</td>
<td width="238">XML file defining menus.</td></tr>
<tr>
<td width="157">/res/values/</td>
<td width="238">File defining various values such as character strings.</td></tr>
<tr>
<td width="157">/res/xml/</td>
<td width="238">Various files saved in the form of XML.</td></tr>
<tr>
<td width="157">/res/raw/</td>
<td width="238">Other files (mp3, mp4 and so on).</td></tr></tbody></table>
<p>The vertical and horizontal mode differs in size on the phone screen. Therefore, if you need both of them to be shown identically, you need to create screen layout file on <strong>/res/layout/</strong> directory. To show differently, create the layout in the <strong>layout-port</strong> (portrait) and <strong>layout-land</strong> (landscape) directories. Also, often you may need to create a <strong>layout</strong> and <strong>layout-land</strong> only. Then files in <strong>layout</strong> will be applied to vertical mode layout.</p>
<h3>Result Directory</h3>
<p>The structure of <strong>bin</strong> (result) directory is as follows.</p>
<table class="blackcap rowbg">
<tbody>
<tr>
<td width="218">bin/classes/</td>
<td width="218">Compiled Java class.</td></tr>
<tr>
<td width="218">bin/classes.dex</td>
<td width="218">Dalvik class file created with compiled Java class.</td></tr>
<tr>
<td width="218">bin/resources.ap_</td>
<td width="218">All resource files (zip) of application.</td></tr>
<tr>
<td width="218">bin/app_name.apk</td>
<td width="218">Android application (zip).</td></tr></tbody></table>
<p>Files that end with “.apk” are the final outcome of Android project, thereby they are ready to be registered in the Android market. The compressed format of this file is zip, which allow us to easily open with compressing programs. However opening this file will not let you decode the meaning since the source files are already compiled.</p>
<h3>AndroidManifest.xml</h3>
<p><strong>AndroidManifest.xml</strong> file is a very important file holding information about the overall structure of the application. Through this file, the Android system finds out component kinds and intent filter and later checks the authority.</p>
<div style="BORDER-BOTTOM: #666666 1px dotted; BORDER-LEFT: #22aaee 5px solid; PADDING-BOTTOM: 5px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; BACKGROUND: url(modules/editor/components/code_highlighter/code.png) #fafafa no-repeat right top; BORDER-TOP: #666666 1px dotted; BORDER-RIGHT: #666666 1px dotted; PADDING-TOP: 5px" editor_component="code_highlighter" nocontrols="false" nogutter="false" collapse="false" first_line="1" description="" file_path="" code_type="plain">&lt;?xml version="1.0" encoding="utf-8"?&gt;<br />&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"<br />package="com.androidside"<br />android:versionCode="1"<br />android:versionName="1.0"&gt;<br />&lt;application android:icon="@drawable/icon"<br />android:label="@string/app_name"&gt;<br />&lt;activity android:name=".HelloWorld"<br />android:label="@string/app_name"&gt;<br />&lt;intent-filter&gt;<br />&lt;action android:name="android.intent.action.MAIN" /&gt;<br />&lt;category android:name="android.intent.category.LAUNCHER" /&gt;<br />&lt;/intent-filter&gt;<br />&lt;/activity&gt;<br />&lt;/application&gt;<br />&lt;uses-sdk android:minSdkVersion="9" /&gt; &lt;!-- android 2.3 --&gt;<br />&lt;/manifest&gt; </div>
<p>AndroidManifest.xml can declare the following elements.</p>
<table class="blackcap rowbg">
<tbody>
<tr>
<td width="201">&lt;uses-permission /&gt;</td>
<td width="276">Authority required by the Application.</td></tr>
<tr>
<td width="201">&lt;permission /&gt;</td>
<td width="276">Authority required by external activity or service.</td></tr>
<tr>
<td width="201">&lt;instrumentation /&gt;</td>
<td width="276">During the occurrence of key events such as activity run, it designates what to call in the application (record, monitoring).</td></tr>
<tr>
<td width="201">&lt;uses-library /&gt;</td>
<td width="276">Designate additional necessary libraries (Google maps).</td></tr>
<tr>
<td width="201">&lt;uses-sdk /&gt;</td>
<td width="276">Android version required for application.</td></tr>
<tr>
<td width="201">&lt;application /&gt;</td>
<td width="276">Application-related information.</td></tr></tbody></table>
<h2>Elements and Structure of Android Application</h2>
<p>Android has <strong>4 key components</strong>:</p>
<ul>
<li>Activity</li>
<li>Service</li>
<li>Broadcast Receiver</li>
<li>And Content Provider</li></ul>
<p>These four components can be closely connected using <strong>Intent</strong>. Below are the key terms and 4 components for Android. Knowing below words will help you understand better Android.</p>
<h3>Android Key Terminology</h3>
<table class="blackcap rowbg">
<tbody>
<tr>
<td width="106">Component</td>
<td width="199">Description</td></tr>
<tr>
<td width="106">Activity</td>
<td width="199">Component for composing UI.</td></tr>
<tr>
<td width="106">Service</td>
<td width="199">Component that runs on the background. No visual UI.</td></tr>
<tr>
<td width="106">Intent</td>
<td width="199">Message element which sends action and data to components.</td></tr>
<tr>
<td width="106">Intent Filter</td>
<td width="199">Defines component by setting intent for receiving.</td></tr>
<tr>
<td width="106">Broadcast Receiver</td>
<td width="199">Receives/responds to a certain broadcast such as lack of battery, language setting/changing. No visual UI.</td></tr>
<tr>
<td width="106">Content Provider</td>
<td width="199">Provides standardized interface for sharing data among applications.</td></tr>
<tr>
<td width="106">Notification</td>
<td width="199">Notifying a certain event to user.</td></tr></tbody></table>
<p>There are various kinds of components for Android, but development using these elements can be described in MVC structure.</p>
<h3>VIEW</h3>
<p>View is for screen composition and this domain can be composed by using the class which inherits View class provided by Android.</p>
<h3>CONTROL</h3>
<p>This domain is for connecting and controlling VIEW and MODEL. <em>Activity</em>, <em>Service </em>and <em>BrodacastReceiver</em> are included.</p>
<h3>MODEL</h3>
<p>This domain is for storing application’s data. <em>SQLite</em>, an embedded database system in Android, <em>File</em> and <em>Content Provider</em>, which can be used for sharing data among applications, are included.</p>
<h2>Conclusion</h2>
<p>Java SDK is, perhaps, one of the most important advantages of Android which provides various powerful functions of Java programming language. However, many developers complain about Android's fast development pace that they have difficulties to catch up. But if we think more positively, this fast-paced transformation seems to have materialized Android to consolidate itself as the most popular mobile platform. On top of that this popularity has led to many patent suits with Microsoft, thus pressuring many carrier providers to inevitably pay patent fees who initially used the technology thinking it was free. Also Oracle’s patent suit against Google citing that Java cannot be used on mobile devices just because Android uses Java. For above reasons and more, the future path of Android might not seem as smooth as before, but we can’t say it will be gloomy either. I hope all these issues will be settled down, and Android will continue to prosper.</p>
<p>By Dong Ho Han, Web Platform Development Lab, NHN Corporation.</p><div id="endic_ext_wrapper"></div>]]></description>
                        <pubDate>Fri, 23 Sep 2011 15:17:31 +0900</pubDate>
                        <category>Android</category>
                        <category>DVM</category>
                        <category>Google</category>
                        <category>Java</category>
                        <category>iOS</category>
                        <category>iPhone</category>
                                    <slash:comments>3</slash:comments>
                    </item>
        										        <item>
            <title>CodeIgniter Officially Supports CUBRID Database</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-appstools/codeigniter-officially-supports-cubrid-database/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-appstools/codeigniter-officially-supports-cubrid-database/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-appstools/codeigniter-officially-supports-cubrid-database/#comment</comments>
                                    <description><![CDATA[<p><img style="FLOAT: left; MARGIN-RIGHT: 10px" alt="CodeIgniter PHP Framework" src="/files/attach/images/220547/212/241/codeigniter_logo.png" width="260" height="300" editor_component="image_link"/> Today I read the great news from CodeIgniter <a href="http://codeigniter.com/forums/viewthread/204822/" target="_self">forum</a>. They have recently released a new 2.1.0 version of their PHP Framework. Great job, CI team! But this is not all. The new release denotes that CI officially supports CUBRID Database. We are very excited about that!</p>
<p>To mention, a few months ago we have developed the <a href="http://blog.cubrid.org/news/cubrid-is-coming-to-codeigniter-php-framework/" target="_self">CUBRID driver for CI</a>, submitted to their new repository at Github, and now we can see the fruits. From now on we will help the CI team to maintain the code.</p>
<p>Feel free to <a href="/downloads#cubrid" target="_self">download CUBRID</a> and give it a try together with CodeIgniter. If you find any DB related bugs, please report them to our <a href="http://jira.cubrid.org/browse/PORTING" target="_self">CUBRID Issue Tracker</a> (JIRA) or <a href="https://github.com/EllisLab/CodeIgniter/issues" target="_self">CI Issue Tracker</a> (Github).<br /></p><p>If you have questions about CUBRID, ask on <a href="/questions" target="_self">CUBRID Q&amp;A</a> site.</p><div id="endic_ext_wrapper" style="display: none; "></div>]]></description>
                        <pubDate>Wed, 23 Nov 2011 13:16:46 +0900</pubDate>
                        <category>PHP</category>
                        <category>CodeIgniter</category>
                        <category>Framework</category>
                                </item>
        										        <item>
            <title>DataCleaner now supports CUBRID Database</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-appstools/datacleaner-now-supports-cubrid-database/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-appstools/datacleaner-now-supports-cubrid-database/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-appstools/datacleaner-now-supports-cubrid-database/#comment</comments>
                                    <description><![CDATA[<p>Have you ever been in a situation when you had to analyze your users' data to check if there was any <strike>naughty</strike>&nbsp;user who had entered some trash text instead of their real first and last names? Or have you been in a situation when you needed an open source tool which would allow you to split your users' full name into first and last names, then&nbsp;automatically&nbsp;insert them into appropriate columns in your database table? Then meet DataCleaner!</p>

<p><img src="http://www.cubrid.org/files/attach/images/220547/014/348/dc-logo.png" alt="DataCleaner" style="float:left;margin-right:10px" width="200" height="200" editor_component="image_link"/><a href="/wiki_apps/entry/datacleaner" target="_self">DataCleaner</a>&nbsp;is&nbsp;an open source <i><b>data quality analyzer</b></i> which can work with CUBRID, Oracle, MS SQL Server, MySQL, PostgreSQL, CSV, and other datasources to help you quickly analyze, clean and profile you data.&nbsp;Its core consists of a strong data profiling engine, which is also extensible, and thereby adds data cleansing, transformations, enrichment, duplicate finding, matching and merging functionalities.</p><p>It is very exciting that DataCleaner now provides support for CUBRID RDBMS in their latest 2.5.1 release.&nbsp;<a href="https://twitter.com/#!/kaspersor" target="_self">Kasper Sørensen</a>, the founder and developer of DataCleaner, says he is "very pleased to see DataCleaner finally supporting the CUBRID database." He added: "With it's focus on web applications I see a tremendous potential for the CUBRID database in conjunction with DataCleaner. And so far the CUBRID community has been a joy serving."</p><p>Here is how Kasper explains why DataCleaner can be a useful tool for Web developers:</p>

<blockquote class="q1"><p>Every self-respecting web application takes user input in one form or another. But as it turns out, we as webapp developers do not always foresee every possible type of user input. So over time data quality issues will occur! Typically what we see happening in web applications is in the form of missing values, fake/spam/made-up values, wrongly formatted database statements leading to values being placed in the wrong fields, duplicated records and so on. All typically because web applications are rapidly being developed and maintained in a quite agile way.</p></blockquote><p>Here is what you can do with DataCleaner:
</p><p></p>

<ul style="list-style-image: url(files/attach/images/220547/014/348/dc-list-icon.png)">
<li>Profile and analyze your database within minutes!</li>
<li>Access almost any datastore - Oracle, MySQL, PostgreSQL, MS SQL Server, MongoDB, CUBRID, CSV files, Excel spreadsheets, DBase and more.</li>
<li>Discover patterns in your textual data with the Pattern Finder.</li>
<li>Find out which values occur the most with the Value Distribution profile.</li>
<li>Cleanse your contact details with name and address validations.</li>
<li>Detect duplicates using fuzzy logic and configurable weights and thresholds.</li>
<li>Merge your duplicates and create a single version of the truth.</li>
<li>Write data back to relational databases, CSV files, Excel spreadsheets or MongoDB databases.</li>
</ul>

<p>Frankly speaking, DataCleaner is so sophisticated that when I ran DataCleaner for the first time, I was stunned by the number of features it provided. For you not to feel lost in this ocean of data analyzing possibilities, I recommend you&nbsp;first&nbsp;to watch some of the&nbsp;<a href="http://datacleaner.eobjects.org/docs#webcasts" target="_self">DataCleaner screencasts</a>&nbsp;available on their project website. Then, based on the video instructions and your needs, you can launch DataCleaner and get started with data cleansing and analysis. We have also created a short&nbsp;<a href="/wiki_apps/entry/datacleaner-cubrid-tutorial" target="_self">tutorial</a>&nbsp;which shows you how to quickly connect DataCleaner to CUBRID Database.</p>

<p>CUBRID community members will certainly benefit much from the whole set of powerful features that DataCleaner provides. On behalf of our community&nbsp;I would like to thank Kasper for his valuable contribution.</p>

<blockquote class="q4"><p style="text-align: center;"><span style="color: rgb(255, 0, 0); "><b>Information for our readers!</b></span></p><p style="text-align: center;"><b>If you develop an open source application</b> and would like to become a <b>CUBRID Partner</b> by supporting CUBRID Database in your project, contact us by email <a href="mailto:affiliates@cubrid.org" target="_self">affiliates@cubrid.org</a>. In your letter please provide an overview of your software, project links, and your statement on behalf of your project. We will be very glad to have you onboard!</p></blockquote>]]></description>
                        <pubDate>Mon, 23 Apr 2012 18:54:13 +0900</pubDate>
                        <category>DataCleaner</category>
                        <category>CUBRID Affiliates</category>
                        <category>Java</category>
                        <category>Data Analyzer</category>
                                </item>
        										        <item>
            <title>Beta version of CUBRID 8.4.1 OLEDB Driver is now available!</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/news/beta-version-of-cubrid-8-4-1-oledb-driver-is-available/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/news/beta-version-of-cubrid-8-4-1-oledb-driver-is-available/</guid>
                        <comments>http://www.cubrid.org/blog/news/beta-version-of-cubrid-8-4-1-oledb-driver-is-available/#comment</comments>
                                    <description><![CDATA[<p>We are very proud to announce the official beta release of&nbsp;<a href="/wiki_apis/entry/cubrid-oledb-driver" target="_self">CUBRID 8.4.1 OLEDB Driver</a>! You can download it right now! It is available under the terms of <a href="/bsd_license" target="_self">BSD License</a>.</p><p>We have created the <a href="/wiki_apis/entry/cubrid-oledb-driver-installation-instructions" target="_self">installation instructions</a>&nbsp;for you&nbsp;which provide three ways to install the driver. Please choose the one you feel more comfortable with.</p><p></p><ol><li>Download the <a href="http://sourceforge.net/projects/cubrid/files/CUBRID-Drivers/OLEDB_Driver/CUBRIDProvider-8.4.1.zip/download" target="_self">compiled library</a> (DLL).</li><li>Download the <a href="http://sourceforge.net/projects/cubrid/files/CUBRID-Drivers/OLEDB_Driver/Installer/CUBRID%20OLE%20DB%20Data%20Provider%208.4.1.exe/download" target="_self">installer</a> (EXE).</li><li>Compile from <a href="http://svn.cubrid.org/cubridapis/oledb/branches/RB-8.4.1/Source/" target="_self">source code</a>.</li></ol>

<p>Right now the beta version supports <b>Win32</b>. The stable version, which should come out in two weeks, will have 64-bit support as well.</p>

<p>If you plan to use the OLEDB driver for .NET projects via <i>System.Data.OleDb</i> namespace, we encourage you to use the fully managed <a href="/wiki_apis/entry/cubrid-ado-net-driver" target="_self">CUBRID ADO.NET driver</a> instead.</p><p></p>

<div><img src="http://www.cubrid.org/files/attach/images/220547/274/350/test-cases.png" alt="test cases.png" width="200" height="275" editor_component="image_link" style="float:left;margin-right:30px" /></div>

<h3>What's new in this version</h3>

<ul><li>The provider naming is set to <i>CUBRID.OLEDBProvider.<b>xxx</b></i> where <b>xxx</b> versioning will be in synch with CUBRID Engine releases.</li><li>In this version we have focused on supporting <a href="http://msdn.microsoft.com/en-us/library/8k76sd16%28v=vs.80%29.aspx" target="_self">OLE DB Consumer templates</a>.&nbsp;Direct OLE DB interfaces work as well even though this technology is already deprecated.</li>
<li>Added BLOB/CLOB support.</li>
<li>Added support for localization (messages, errors content).</li>
<li>Added Installer for the provider library.</li><li>Enhanced schema rowsets support.</li><li>Added test cases coverage. There are now 60+ test cases available!</li>
</ul>

<h3>Improvements in the coming stable release</h3><p></p><ul><li><i>Add <b>BLOB/BLOB</b> Dynamic Accessors&nbsp;support in the stable release.</i></li><li><i>Add schema support for <b>CUBRID Stored Procedures</b>.</i></li>
<li><i>Improve support for Auto-Commit mode. Currently the <b>Update()</b> support is restricted to <b>Auto-Commit mode = Off</b>, which must be explicitly stated via session transaction.</i></li>
<li><i>Add support for <b>cci_connect_with_url</b>. Improve <b>UTF-8</b> support.</i></li>
<li><i>Add support for the new <b>cci_prepare_and_execute</b> function.</i></li>
<li><i>Add <b>more test cases</b> coverage, in particular for CUBRID specific data types and for .NET OleDb access.</i></li>
<li><i>Remove the data provider distribution from the CUBRID standard installer.</i></li>
<li><i>Release 64-bit version.</i></li><li><i><span class="Apple-style-span" style="font-style: normal; "><i>Publish Doxygen documentation.</i></span></i></li><li><i><span class="Apple-style-span" style="font-style: normal; "><i><span class="Apple-style-span" style="font-style: normal; "><i>SVN cleanup.</i></span></i></span></i></li></ul><p></p><p>More information about this beta release you can find in the <a href="/wiki_apis/entry/cubrid-oledb-driver-release-notes" target="_self">OLEDB Release Note</a>.</p><p>In conclusion, I would like to invite all users to help us verify this beta version. If you find any bug, please report to our&nbsp;<a href="http://jira.cubrid.org/browse/APIS/component/10104" target="_self">Issue Tracker</a>.</p><p>And one more time, we will release the stable version in about two weeks from now, so stay tuned!</p><p>


</p>]]></description>
                        <pubDate>Fri, 27 Apr 2012 13:58:02 +0900</pubDate>
                        <category>OLEDB</category>
                        <category>ADO.NET</category>
                        <category>Driver</category>
                                </item>
        										        <item>
            <title>How Statement Pooling in JDBC affects the Garbage Collection</title>
            <dc:creator>Dongsun Choi</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/how-statement-pooling-in-jdbc-affects-garbage-collection/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/how-statement-pooling-in-jdbc-affects-garbage-collection/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/how-statement-pooling-in-jdbc-affects-garbage-collection/#comment</comments>
                                    <description><![CDATA[<p>There are various techniques to improve the performance of your Java application. In this article I will talk about <b>Statement Pooling Configuration</b>&nbsp;and <b>its effect on Garbage Collection process</b>.</p><p>Statement Pooling allows to improve the performance of an application by caching SQL statements that are used repeatedly.&nbsp;Such caching mechanism allows to prepare frequently used statements only once and reuse them multiple times, thus reducing the overall number of times the database server has to parse, plan, and optimize these queries.&nbsp;A well-configured number of statements (<span style="font-family: monospace; ">maxStatements</span>) to be cached can be as good as tuning the <a href="/blog/tags/Garbage%20Collection/" target="_self">Garbage Collection</a>. Now let's see how Statement Pooling can affect the Garbage Collection.</p><p></p><h2>Why Check the Number of Statement in the Pool?</h2><p>Often the size of the JDBC statement pool is set to the default value. Using the default value, of course does not usually lead to any special issue. But a well-configured <span style="font-family: monospace; ">maxStatements</span> value can be as effective as GC tuning. If you are using the default <span class="Apple-style-span" style="font-family: monospace; ">maxStatements</span> value and would like to optimize the use of memory, let's think about the correct statement pool value before attempting GC tuning.</p><p>As was discussed in <a href="/blog/dev-platform/understanding-java-garbage-collection/" target="_self">Understanding Java Garbage Collection</a>, a <b>weak generational hypothesis</b>&nbsp;(<i>most objects quickly become unreachable and a reference from an old object to a new object is rare</i>) was used as the precondition when creating garbage collector in Java. For the majority of <a href="/blog/tags/NHN/" target="_self">NHN</a> web services there should be a response within <span style="font-family: monospace; ">300ms</span> at the latest, unless it is a special case. Therefore, NHN web services are more applicable to the above situations than the general stand-alone type applications.</p><h2>The GC Process between HTTP Request and Response</h2><p>When developing a web service using web containers like Tomcat and other frameworks, the lifespan of objects created by a developer tend to be either very short or very long.&nbsp;Web developers usually write codes like Interceptor, Action, BO, or DAO (<i>BO and DAO are generated and used as singletons from applicationContex in Spring, and are not the target of GC</i>). The objects generated from these codes stay alive for a very brief time that exists <b>between the time</b> HTTP is <b>requested</b> and the time it has&nbsp;<b>responded</b>. For this reason, such objects are usually collected during <a href="/blog/dev-platform/understanding-java-garbage-collection/" target="_self">Young GC</a>.</p><p>There are&nbsp;also&nbsp;objects, such as <b><i>singleton objects</i></b>, that stay alive long enough to exist for the lifecycle of Tomcat. Such objects will be promoted to the <i><b>old</b></i> area soon after Tomcat starts running.&nbsp;Yet, when continuously <a href="/blog/dev-platform/how-to-monitor-java-garbage-collection/" target="_self">monitoring web applications</a> through <b>jstat</b> and the like, there are always some objects promoted to the <i>old</i> area during Young GC.&nbsp;These objects are usually used <i>after being stored in the cache</i> used for improving the performance of frameworks in most of the containers and projects. Whether the cached objects become the target of GC or not is determined by their <i><b>cache hit ratio</b></i>, not their age, so unless the hit ratio is 100%, they cannot avoid being promoted to the old area, even when the Young GC cycle is set to be long.</p><p>Among these caches, <b>statement pooling affects the memory usage the most</b>. If you are using <b>iBatis</b>, as iBatis processes all SQLs as preparedStatment, you will be using statement pooling.&nbsp;<i>If the size of statement pooling is smaller than the number of SQLs being used</i>, the cache hit ratio will decrease and result in <i><b>cache maintenance cost</b></i>. Objects that are reachable in the old area become the target of GC and will be retrieved, then will be regenerated during the HTTP request process, only to be cached and promoted to the old area. The full GC cycles are affected by this process.</p><h2>Size of the Statement Objects</h2><p>It would be safe to say that the size of a single statement object is proportional to the length of the SQL code processed by the same statement. Even for a long and complex SQL, the size of the object should be around 500 bytes. The object's small size would seem to have little effect on the full GC cycles, but <b>such an assumption would be incorrect</b>.&nbsp;</p><p>When you look at the JDBC specifications, each connection has its own statement pool (<span style="font-family: monospace; ">maxStatementsPerConnection</span>), as described in <b>Figure 1</b> below. So, although a statement object is as small as 500 bytes, if there are many connections, the statements cache may occupy the proportional amount of the heap.&nbsp;</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/817/348/relationship-between-connection-and-statement.png" alt="relationship-between-connection-and-statement.png" width="397" height="319" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 1: Relationship between the Connection and the Statement.</b><br /><i>(Though the statement has the ResultSet, it should be clarified that ResultSet is not an object for caching.&nbsp;ResultSet is allocated as null when rs.close() is called by iBatis, then retrieved in the young area during young GC.)</i></p><h2>The Effect of Statement Pool's Cache Hit Ratio on the Full GC</h2><p>A simple test program was created to <b>assess the effect of cache hit ratio on the full GC</b>. One cache hit ratio was set to 100% while the other was set to 50%. When the same amount of load was applied, the results presented in <b>Table 1</b> and <b>2</b> were obtained.</p><p>In both cases, the occurrences of young GC were very similar but the results for the full GC was different. When the cache hit ratio was 100%, full GC occurred only once, because the number of objects promoted to the old area during young GC was small. When the ratio was 50%, full GC occurred 4 times because the number of statement objects promoted to the old area during young GC was high, as the objects were cached in the statement pool, then removed from the pool in LRU way, then cached again at the next request.</p>

<p><b>Table 1. Cache hit ratio = 100%.</b></p>

<table>
<thead>
	<tr>
		<td>...</td>
		<td>OC</td>
		<td>OU</td>
		<td>YGC</td>
		<td>FGC</td>
		<td>FGCT</td>
		<td>GCT</td>
	</tr>
</thead>
<tbody>
	<tr>
		<td>...</td>
		<td>10688.0</td>
		<td>6940.9</td>
		<td>532</td>
		<td>1</td>
		<td>0.190</td>
		<td>1.274</td>
	</tr>
	<tr>
		<td>...</td>
		<td>10688.0</td>
		<td>6940.9</td>
		<td>532</td>
		<td>1</td>
		<td>0.190</td>
		<td>1.274</td></tr></tbody></table><p></p><p><b>Table 2. Cache hit ratio = 50%.</b></p>

<table>
<thead>
	<tr>
		<td>...</td>
		<td>OC</td>
		<td>OU</td>
		<td>YGC</td>
		<td>FGC</td>
		<td>FGCT</td>
		<td>GCT</td>
	</tr>
</thead>
<tbody>
	<tr>
		<td>...</td>
		<td>10240.0</td>
		<td>7092.7</td>
		<td>554</td>
		<td>4</td>
		<td>0.862</td>
		<td>2.253</td>
	</tr>
	<tr>
		<td>...</td>
		<td>10240.0</td>
		<td>7412.0</td>
		<td>555</td>
		<td>4</td>
		<td>0.862</td>
		<td>2.255</td></tr></tbody></table><p>I would like to add one more thing. When the cache hit ratio is 50%, it violates the 2nd category of <i>weak generational hypothesis</i> I introduced previously. When low <i>cache hit ratio</i> causes frequent pool registration and subsequent removal, it means the statement object generated in the young area is being referenced in the pool from the old area, which leads to additional strain during GC because the <i><a href="/blog/dev-platform/understanding-java-garbage-collection/" target="_self">card marking technique</a></i> is used to manage the references separately.</p><h2>In Conclusion</h2><p>In Lucy (NHN's internal Java Framework), the <span style="font-family: monospace; ">maxStatements</span> value for statement pooling in Oracle and MySQL is <b><span style="font-family: monospace; ">500</span></b>. In most cases, 500 should be enough. However, when more SQL is being used, increasing the default value to meet such demand would be a way to improve the system efficiency (w<i>hen using $(String replacement) for query on iBatis for the reason of table partitioning and the like, the number of queries must be multiplied by the number of partitioned tables</i>).</p><p>However, when the default value is higher than necessary, this leads to a different problem. A higher value means more memory usage and higher likelihood of an Out Of Memory (OOME) occurrence.</p><p>In a situation where the number of SQLs are 10,000 and the number of connections are 50, then the total size of statement objects is about 250 MB. (500 byte * 50 * 10,000 = 250 MB).&nbsp;It should be easy to determine the likelihood of OOME occurrence by checking the Xmx configuration for the service in use.</p><p>What strategy do you follow to determine the correct number of statements to be pooled? Share your experience in the comments below.</p><p></p><p>By Dongsun Choi, Senior Engineer at Game Service Solution Team, NHN Corporation.</p><p>


</p>]]></description>
                        <pubDate>Tue, 24 Apr 2012 11:55:23 +0900</pubDate>
                        <category>Statement Pooling</category>
                        <category>Garbage Collection</category>
                        <category>Java</category>
                        <category>NHN</category>
                        <category>performance</category>
                        <category>tuning</category>
                        <category>JDBC</category>
                                    <slash:comments>2</slash:comments>
                    </item>
        										        <item>
            <title>What is Nginx?</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/what-is-nginx/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/what-is-nginx/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/what-is-nginx/#comment</comments>
                                    <description><![CDATA[<p>Apache which had been at the forefront of web revival is now giving its way to Nginx. Nginx is spreading at a fast pace worldwide, and at <a title="NHN - CUBRID Blog" href="http://blog.cubrid.org/tags/nhn/">NHN</a> as well we have been replacing web servers by Nginx more and more.</p>

<p>Let’s look at what Nginx is and how it differs from Apache Web Server.</p>

<p>In the beginning of 21<sup>st</sup> century as the use of internet became more active, people began to shed more interest on web servers capable of processing more requests. Later the <a title="The C10K problem" href="http://www.kegel.com/c10k.html">C10k problem</a> emerged in this era, in other words to enable each web server to be capable of processing 10,000 clients at the same time. Therefore a need to develop a better Network I/O and Thread management technology was emerged. During this period, far less-developed technology was applied to Linux than previous ones such as <b>epoll</b> and <b>NPTL</b>.</p>

<blockquote><b>epoll</b> was designed for better process of IO events on Linux. kqueue (FreeBSD) and IOCP (Windows) are similar. <b>NPTL</b> is a thread library of Linux loaded on Kernel 206 and up (based on safe version). It provided enormous improvement in thread performance.</blockquote>

<p>It is fair to say that the emergence of several technology was not the result of an effort to tackle C10k problem (as a common problem) but "The C10k problem" succeeded in putting together efforts to enhance performance of network server development. As a result various web servers such as <b>Nginx</b>, <b>Lightpad</b> and <b>Cherokee</b> made with new technology were in the market.</p>

<a name="more"></a>
<p>Nginx was first developed by a Russian guy called Igor Sysoev in 2002. After two years in 2004 it made its debut in the forms of  HTTP server and reverse proxy/IMAP/POP3 server. To respond to C10k problem, Nginx adopted event-driven (asynchronous) structure which is not a conventional way (as in Apache) of processing single client in a single thread. Other than Nginx, various newly developed web servers such as Lightpad, Tornado, Magnum and Aleph have adopted Event-driven structure too.</p>

<h2>Event-driven Architecture (EDA)</h2>

<p>EDA method is capable of handling more number of clients with less threads compared to conventional way (one thread for one client). In Apache each thread is dedicated to handle one client. So, there will be many cases when a certain thread needs to be on hold due to I/O problems until certain data is read from persistence layer in "accept" and delivered to the client. There should be the same number of threads as that of clients.</p>

<p>However, with EDA a method enables event (i.e. when event needs to be created or response result is completed) to be processed every time it takes place by designating each state. In other words, with less thread (or even without any thread) CPU can be used more efficiently.</p>

<p>Nginx provides almost all the functions Apache web server does. For example:</p>

<ul>
  <li>handling of static files</li>
  <li>reverse proxy</li>
  <li>load balancing</li>
  <li>SSL support</li>
  <li>FastCGI</li>
  <li>Virtual Host</li>
  <li>FLV Streaming</li>
  <li>MP4 streaming</li>
  <li>Web page access authentication</li>
  <li>gzip</li>
  <li>URL Rewriting</li>
  <li>Custom Logging</li>
  <li>SSI</li>
  <li>WebDAV</li>
</ul>
<h2>Nginx Use</h2>

<p>According to a research done in April, 2011 by W3Techs.com, Nginx takes up 6.9% in web server market and is on a steady increase. The graph below shows the market share of Nginx in recent 1 year.</p>

<p><a href="http://blog.cubrid.org/wp-content/uploads/2011/09/nginx-usage.png"><img title="Usage of Nginx for Web sites, 18 Apr 2011, W3Techs.com" src="http://blog.cubrid.org/wp-content/uploads/2011/09/nginx-usage.png" width="500" height="281" editor_component="image_link"/></a></p>

<p>We can see that many websites process massive traffic using Nginx. Alexa.com is well known for releasing website ranking according to its traffic. The following list, released on April 18, 2011, illustrates websites from <a title="Top Sites by Alexa.com" href="http://www.alexa.com/topsites">Top 500</a> which use Nginx.</p>

<table class="blackcap rowbg">
<thead>
<tr>
<td width="45">Ranking</td>
<td width="253">Websites</td>
</tr>
</thead>
<tbody>
<tr>
<td width="45">10</td>
<td width="253">qq.com</td>
</tr>
<tr>
<td width="45">15</td>
<td width="253">Taobao.com</td>
</tr>
<tr>
<td width="45">19</td>
<td width="253">WordPress.com</td>
</tr>
<tr>
<td width="45">23</td>
<td width="253">Yandex.ru</td>
</tr>
<tr>
<td width="45">28</td>
<td width="253">163.com</td>
</tr>
<tr>
<td width="45">45</td>
<td width="253">Vkontakte.ru</td>
</tr>
<tr>
<td width="45">54</td>
<td width="253">Soso.com</td>
</tr>
<tr>
<td width="45">63</td>
<td width="253">Wordpress.org</td>
</tr>
<tr>
<td width="45">83</td>
<td width="253">Youporn.com</td>
</tr>
<tr>
<td width="45">109</td>
<td width="253">Twitpic.com</td>
</tr>
<tr>
<td width="45">116</td>
<td width="253">Imageshack.us</td>
</tr>
<tr>
<td width="45">133</td>
<td width="253">Badoo.com</td>
</tr>
<tr>
<td width="45">140</td>
<td width="253">Sourceforge.net</td>
</tr>
<tr>
<td width="45">206</td>
<td width="253">Scribd.com</td>
</tr>
<tr>
<td width="45">259</td>
<td width="253">Hulu.com</td>
</tr>
</tbody>
</table>

<h2>Characteristics of Nginx</h2>

<h3>Non-blocking  event-driven method</h3>

<p>The most notable characteristic of Nginx is that it uses non-blocking event-driven method. All the network connection operates in non-blocking way. Some socket interfaces return results immediately, while some are blocked in certain cases. <b>Socket()</b> and <b>setsockopt()</b> returns results without blocking, whereas <b>connect()</b>, <b>send()</b>, <b>recv()</b> and <b>close()</b> might experience some blocking in certain cases. Nginx calls above mentioned functions only after confirming there will be no lags. In order to prevent blocking, as for <b>connect()</b>, socket is changed in advance to non-blocking using <b>ioctl()</b>.</p>

<p>As for <b>send()</b> and <b>recv()</b>, <b>epoll</b> is used to confirm blocklessness. Codes for calling <b>send()</b> or <b>recv()</b> are composed in event-driven format. Each event is composed of a socket, a socket state and an operating function. Almost all of internal Nginx is operated in event-driven way since web server processes request from web browser through network.</p>

<h3>Single thread</h3>

<p>Nginx is operated by pre-set number of worker processes. Each process operates as a single thread. Also, the need for multi-thread is relatively low since with the use of Non-blocking event-driven allows a single worker process to handle requests by multiple clients.</p>

<h2>Advantage of Nginx</h2>

<h3>High Performance</h3>

<p>Generally Nginx is known to record higher performance than Apache. However, we cannot simply jump to conclusion in terms of better performance since it varies greatly according to workload. Below chart indicates a system function that is called to serve a single <em>favicon.ico</em> using starce. As you can see in the table below Apache called 31 system functions whereas Nginx called 16. Although the system function used here cannot accurately indicate the performance, we can still expect relative performance.</p>

<table class="blackcap rowbg">
<thead>
<tr>
<td width="121" valign="top" class="xe_selected_cell">System Function</td>
<td width="101" valign="top" class="xe_selected_cell">Apache</td>
<td width="83" valign="top" class="xe_selected_cell">Nginx</td>
</tr>
</thead>
<tbody>
<tr>
<td width="121" valign="top" class="xe_selected_cell">accept()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">close()</td>
<td width="101" valign="top" class="xe_selected_cell">2</td>
<td width="83" valign="top" class="xe_selected_cell">2</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">epoll_ctl()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">epoll_wait()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">2</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">fcntl64()</td>
<td width="101" valign="top" class="xe_selected_cell">6</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">fstat64()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">getsockname()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">gettimeofday()</td>
<td width="101" valign="top" class="xe_selected_cell">9</td>
<td width="83" valign="top" class="xe_selected_cell">2</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">ioctl()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">open()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">poll()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">read()</td>
<td width="101" valign="top" class="xe_selected_cell">3</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">recv()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">sendfile64()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">setsockopt()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">shutdown()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">stat64()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">0</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">times()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">write()</td>
<td width="101" valign="top" class="xe_selected_cell">0</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">writev()</td>
<td width="101" valign="top" class="xe_selected_cell">1</td>
<td width="83" valign="top" class="xe_selected_cell">1</td>
</tr>
<tr>
<td width="121" valign="top" class="xe_selected_cell">Total</td>
<td width="101" valign="top" class="xe_selected_cell">31</td>
<td width="83" valign="top" class="xe_selected_cell">16</td>
</tr>
</tbody>
</table><div style="text-align: left;">

</div>
<h4 style="text-align: left;">Handling many clients with less process</h4><div style="text-align: left;">

</div><div style="text-align: left;">In case of Apache, one process or thread is needed to handle the one client, whereas Nginx only requires a little memory for the same work. Therefore, with the same amount of resource, Nginx is capable of supporting far more number of clients compared to Apache.</div>
<h3 style="text-align: left;">Disadvantage of Nginx</h3><div style="text-align: left;">

</div>
<h4 style="text-align: left;">Difficult to create module</h4><div style="text-align: left;">

</div><div style="text-align: left;">It is notorious that Nginx gives a hard time when creating modules. There is an interface called Apache Portable Runtime (APR) in Apache Web Server. The Module Creator of Apache Web Server creates a module after reading APR document using the necessary function. However with Nginx, there is no such function as APR, therefore the creator needs to find the function needed for creating the module within the internal code of Nginx.</div>
<h4 style="text-align: left;">Does not support HTTP/1.1 in communication with Backend</h4><div style="text-align: left;">

</div><div style="text-align: left;">HTTP/1.1 is supported for a communication between web browser and Nginx however only HTTP/1.0 is supported between Nginx and Backend server. Luckily, with a recent development of AJP module, it can now replace HTTP/1.0 for connecting Nginx and Tomcat.</div>
<h3 style="text-align: left;">Things to note while using Nginx</h3><div style="text-align: left;">

</div>
<ul><div style="text-align: left;">

</div>
  <li style="text-align: left;">Nginx has a non-blocking event-driven structure. Such structure is desirable for network transmission and reception. However, it could generate blocking when file is being sent and received. But the latest Linux versions support Asynchronous Input-Output (AIO), and Nginx began to support AIO since version 0.8.11.</li><div style="text-align: left;">

</div>
  <li style="text-align: left;">Nginx uses AIO function through <b>eventfd()</b> system function of Linux. However it only works when AIO of Linux is set as <b>DirectIO</b>. Thus, using AIO on Linux disables buffer cache of OS.</li><div style="text-align: left;">

</div>
  <li style="text-align: left;">As in the case of reading the same file over and over again, it reads from disk in the first place however from the second time it can rapidly read stored file on buffer cache. No matter how many times the file is being read, using DirectIO makes it to be read from disk consistently.</li><div style="text-align: left;">

</div>
  <li style="text-align: left;">If a DBMS uses independent buffer, DirectIO might be efficient. However in other cases DirectIO could decrease file input/output performance.</li><div style="text-align: left;">

</div>
  <li style="text-align: left;">If most of the files that Nginx read exist in OS buffer cache, most of file I/O become non-blocking. However if Nginx gets to serve files which do not existent in the buffer cache, the worker process becomes blocked due to file I/O. In this case, you need to increase the number of worker processes in order to prevent the worker process from becoming blocking.</li><div style="text-align: left;">

</div>
</ul><div style="text-align: left;">

</div><div style="text-align: left;">By Heum-geun Kang, Main Service Development Team, NHN Corporation.</div>]]></description>
                        <pubDate>Mon, 13 Feb 2012 10:57:50 +0900</pubDate>
                        <category>Nginx</category>
                        <category>Web Server</category>
                        <category>Apache</category>
                                    <slash:comments>6</slash:comments>
                    </item>
        										        <item>
            <title>How to Monitor Java Garbage Collection</title>
            <dc:creator>Sangmin Lee</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/how-to-monitor-java-garbage-collection/#comment</comments>
                                    <description><![CDATA[<p>This is the second article in the series of "<i><a href="/blog/tags/Garbage%20Collection/" target="_self">Become a Java GC Expert</a></i>".&nbsp;In the first issue <a href="/blog/dev-platform/understanding-java-garbage-collection/" target="_self">Understanding Java Garbage Collection</a> we have learned about the processes for different GC algorithms, about how GC works, what Young and Old Generation is, what you should know about the 5 types of GC in the new JDK 7, and what the performance implications are for each of these GC types.</p><p>In this article, I will explain <b>how&nbsp;<a href="/blog/dev-platform/understanding-jvm-internals/" target="_self">JVM</a> is actually running Garbage Collection in the real time</b>.</p><p></p><h2>What is GC Monitoring?&nbsp;</h2><p><b>Garbage Collection Monitoring</b> refers to the <i>process of figuring out how JVM is running GC</i>. For example, we can find out:</p><p></p><ol><li>when an object in young has moved to old and by how much,</li><li>or when <a href="/blog/dev-platform/understanding-java-garbage-collection/#stop-the-world" target="_self">stop-the-world</a> has occurred and for how long.</li></ol><p></p><p>GC monitoring is carried out <i>to see if JVM is running GC efficiently</i>, and <i>to check if additional GC tuning is necessary</i>.&nbsp;Based on this information, the application can be edited or GC method can be changed (<b>GC tuning</b>).</p><h2>How to Monitor GC?</h2><p>There are different ways to monitor GC, but the only difference is how the GC operation information is shown. GC is done by JVM, and since the GC monitoring tools disclose the GC information provided by JVM, you will get the same results no matter how you monitor GC. Therefore, you do not need to learn all methods to monitor GC, but since it only requires a little amount of time to learn each GC monitoring method, knowing a few of them can help you use the right one for different situations and environments.</p><p>The tools or JVM options listed below cannot be used universally regardless of the HVM vendor. This is because there is no need for a "standard" for disclosing GC information. In this example we will use <b>HotSpot JVM</b> (Oracle JVM). Since <a href="/blog/tags/NHN/" target="_self">NHN</a> is using Oracle (Sun) JVM, there should be no difficulties in applying the tools or JVM options that we are explaining here.</p><p>First, the GC monitoring methods can be separated into <b>CUI</b> and <b>GUI</b> depending on the access interface. The typical CUI GC monitoring method involves using a separate CUI application called "<b>jstat</b>", or selecting a JVM option called "<b>verbosegc</b>" when running JVM.</p><p>GUI GC monitoring is done by using a separate GUI application, and three most commonly used applications would be "jconsole", "jvisualvm" and "Visual GC".</p><p>Let's learn more about each method.</p><h2>jstat</h2><p><b>jstat</b> is a monitoring tool in HotSpot JVM. Other monitoring tools for HotSpot JVM are <b>jps</b> and <b>jstatd</b>. Sometimes, you need all three tools to monitor a Java application.</p><p><b>jstat</b> does not provide only the GC operation information display. It also provides class loader operation information or Just-in-Time compiler operation information. Among all the information jstat can provide,&nbsp;in this article&nbsp;we will only cover its functionality to <i>monitor</i> GC operating information.</p><p><b>jstat</b> is located in <span style="background-color: rgb(214, 212, 235); "><span style="background-color: rgb(214, 212, 235); ">$JDK_HOME/bin</span></span>, so if <i>java</i> or <i>javac</i> can run without setting a separate directory from the command line, so can jstat.</p><p>You can try running the following in the command line.</p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">
$&gt; jstat –gc  $&lt;vmid$&gt; 1000<br /><br />

S0C &nbsp; &nbsp; &nbsp; S1C &nbsp; &nbsp; &nbsp; S0U &nbsp; &nbsp;S1U &nbsp; &nbsp; &nbsp;EC &nbsp; &nbsp; &nbsp; &nbsp; EU &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OC &nbsp; &nbsp; &nbsp; &nbsp; OU &nbsp; &nbsp; &nbsp; &nbsp; PC &nbsp; &nbsp; &nbsp; &nbsp; PU &nbsp; &nbsp; &nbsp; &nbsp; YGC &nbsp; &nbsp; YGCT &nbsp; &nbsp;FGC &nbsp; &nbsp; &nbsp;FGCT &nbsp; &nbsp; GCT<br />
3008.0 &nbsp; 3072.0 &nbsp; &nbsp;0.0 &nbsp; &nbsp; 1511.1 &nbsp; 343360.0 &nbsp; 46383.0 &nbsp; &nbsp; 699072.0 &nbsp; 283690.2 &nbsp; 75392.0 &nbsp; &nbsp;41064.3 &nbsp; &nbsp;2540 &nbsp; &nbsp;18.454 &nbsp; &nbsp;4 &nbsp; &nbsp; &nbsp;1.133 &nbsp; &nbsp;19.588<br />
3008.0 &nbsp; 3072.0 &nbsp; &nbsp;0.0 &nbsp; &nbsp; 1511.1 &nbsp; 343360.0 &nbsp; 47530.9 &nbsp; &nbsp; 699072.0 &nbsp; 283690.2 &nbsp; 75392.0 &nbsp; &nbsp;41064.3 &nbsp; &nbsp;2540 &nbsp; &nbsp;18.454 &nbsp; &nbsp;4 &nbsp; &nbsp; &nbsp;1.133 &nbsp; &nbsp;19.588<br />
3008.0 &nbsp; 3072.0 &nbsp; &nbsp;0.0 &nbsp; &nbsp; 1511.1 &nbsp; 343360.0 &nbsp; 47793.0 &nbsp; &nbsp; 699072.0 &nbsp; 283690.2 &nbsp; 75392.0 &nbsp; &nbsp;41064.3 &nbsp; &nbsp;2540 &nbsp; &nbsp;18.454 &nbsp; &nbsp;4 &nbsp; &nbsp; &nbsp;1.133 &nbsp; &nbsp;19.588<br /><br />
$&gt;</div>

<p></p><p>Just like in the example, the real type data will be output along with the following columns: <span style="background-color: rgb(231, 219, 237); "><span style="background-color: rgb(231, 219, 237); "><b>S0C &nbsp; &nbsp;S1C &nbsp; &nbsp; S0U &nbsp; &nbsp; S1U &nbsp; &nbsp;EC &nbsp; &nbsp; EU &nbsp; &nbsp; OC &nbsp; &nbsp; OU &nbsp; &nbsp; PC</b></span></span>.</p><p><b>vmid</b> (Virtual Machine ID), as its name implies, is the <b>ID</b> for the VM. Java applications running either on a local machine or on a remote machine can be specified using vmid. The vmid for Java application running on a local machine is called <b>lvmid</b> (Local vmid), and usually is PID. To find out the lvmid, you can write the PID value using a <b><span style="background-color: rgb(214, 212, 235); ">ps</span></b> command or Windows task manager, but we suggest <b>jps</b> because PID and lvmid does not always match. <b>jps</b> stands for Java PS. jps shows <i>vmids</i> and main method information. Just like ps shows PIDs and process names.</p><p>Find out the vmid of the Java application that you want to monitor by using jps, then use it as a parameter in jstat. If you use jps alone, only bootstrap information will show when several WAS instances are running in one equipment. We suggest that you use <span style="background-color: rgb(214, 212, 235); "><span style="background-color: rgb(214, 212, 235); "><b>ps -ef | grep java</b></span></span> command along with <b>jps</b>.</p><p>GC performance data needs constant observation, therefore when running jstat, try to output the GC monitoring information on a regular basis.&nbsp;</p><p>For example, running "<b><span style="background-color: rgb(214, 212, 235); ">jstat –gc &lt;vmid&gt; 1000</span></b>" (or 1s) will display the GC monitoring data on the console every 1 second. "<b><span style="background-color: rgb(214, 212, 235); ">jstat –gc &lt;vmid&gt; 1000 10</span></b>" will display the GC monitoring information once every 1 second for 10 times in total.</p><p>There are many options other than <b>-gc</b>, among which GC related ones are listed below.</p>

<table>
<thead>
	<tr>
		<td>Option Name</td>
		<td>Description</td>
	</tr>
</thead>
<tbody>
	<tr>
		<td>gc</td>
		<td>It shows the current size for each heap area and its current usage (Ede, survivor, old, etc.), total number of GC performed, and the accumulated time for GC operations.</td>
	</tr>
	<tr>
		<td>gccapactiy</td>
		<td>It shows the minimum size (ms) and maximum size (mx) of each heap area, current size, and the number of GC performed for each area. (Does not show current usage and accumulated time for GC operations.)</td>
	</tr>
	<tr>
		<td>gccause</td>
		<td>It shows the "information provided by -gcutil" + reason for the last GC and the reason for the current GC.</td>
	</tr>
	<tr>
		<td>gcnew</td>
		<td>Shows the GC performance data for the new area.</td>
	</tr>
	<tr>
		<td>gcnewcapacity</td>
		<td>Shows statistics for the size of new area.</td>
	</tr>
	<tr>
		<td>gcold</td>
		<td>Shows the GC performance data for the old area.</td>
	</tr>
	<tr>
		<td>gcoldcapacity</td>
		<td>Shows statistics for the size of old area.</td>
	</tr>
	<tr>
		<td>gcpermcapacity</td>
		<td>Shows statistics for the permanent area.</td>
	</tr>
	<tr>
		<td>gcutil</td>
		<td>Shows the usage for each heap area in percentage. Also shows the total number of GC performed and the accumulated time for GC operations.</td>
	</tr>
</tbody>
</table>

<p>Only looking at frequency, you will probably use <b>-gcutil</b> (or -gccause), <b>-gc</b> and <b>-gccapacity</b> the most in that order.</p><p></p><ul><li><b>-gcutil</b> is used to check the usage of heap areas, the number of GC performed, and the total accumulated time for GC operations,</li><li>while <b>-gccapacity</b> option and others can be used to check the actual size allocated.</li></ul><p></p><p>You can see the following output by using the <b><span style="background-color: rgb(214, 212, 235); ">-gc</span></b> option:</p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;"><p>S0C<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp; &nbsp;S1C<span class="Apple-tab-span" style="white-space:pre">	</span>…<span class="Apple-tab-span" style="white-space:pre">	</span>GCT<br />1248.0<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp;896.0<span class="Apple-tab-span" style="white-space:pre">	</span>…<span class="Apple-tab-span" style="white-space:pre">	</span>1.246<br />1248.0&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp;896.0<span class="Apple-tab-span" style="white-space:pre">	</span>…<span class="Apple-tab-span" style="white-space:pre">	</span>1.246<br />…<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp; &nbsp;…<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp; …<span class="Apple-tab-span" style="white-space:pre">	</span>…</p></div><p></p><p></p><p>Different jstat options show different types of columns, which are listed below. Each column information will be displayed when you use the "jstat option" listed on the right.</p>

<table>
 <thead>
	<tr>
		<td>Column</td>
		<td style="width:530px">Description</td>
		<td>Jstat Option</td>
	</tr>
 </thead>
 <tbody>
	<tr>
		<td class="">S0C</td>
		<td class="">Displays the current size of Survivor0 area in KB</td>
		<td class="">-gc<br />
  -gccapacity<br />
  -gcnew<br />
  -gcnewcapacity</td>
	</tr>
	<tr>
		<td>S1C</td>
		<td>Displays the current size of Survivor1 area in KB</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcnew<br />
  -gcnewcapacity</td>
	</tr>
	<tr>
		<td>S0U</td>
		<td>Displays the current
  usage of Survivor0 area in KB</td>
		<td>-gc<br />
  -gcnew</td>
	</tr>
	<tr>
		<td>S1U</td>
		<td>Displays the current
  usage of Survivor1 area in KB</td>
		<td>-gc<br />
  -gcnew</td>
	</tr>
	<tr>
		<td>EC</td>
		<td>Displays the current size of Eden area in KB</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcnew<br />
  -gcnewcapacity</td>
	</tr>
	<tr>
		<td>EU</td>
		<td>Displays the current usage of Eden area in KB</td>
		<td>-gc<br />
  -gcnew</td>
	</tr>
	<tr>
		<td>OC</td>
		<td>Displays the current size of old area in KB</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcold<br />
  -gcoldcapacity</td>
	</tr>
	<tr>
		<td>OU</td>
		<td>Displays the current usage of old area in KB</td>
		<td>-gc<br />
  -gcold</td>
	</tr>
	<tr>
		<td>PC</td>
		<td>Displays the current size of permanent area in KB</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcold<br />
  -gcoldcapacity<br />
  -gcpermcapacity</td>
	</tr>
	<tr>
		<td>PU</td>
		<td>Displays the current usage of permanent area in KB</td>
		<td>-gc<br />
  -gcold</td>
	</tr>
	<tr>
		<td>YGC</td>
		<td>The number of GC event occurred in young area</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcnew<br />
  -gcnewcapacity<br />
  -gcold<br />
  -gcoldcapacity<br />
  -gcpermcapacity<br />
  -gcutil<br />
  -gccause</td>
	</tr>
	<tr>
		<td>YGCT</td>
		<td>The accumulated time for GC operations for Yong area <span></span></td>
		<td>-gc<br />
  -gcnew<br />
  -gcutil<br />
  -gccause</td>
	</tr>
	<tr>
		<td>FGC</td>
		<td>The number of full GC event occurred</td>
		<td>-gc<br />
  -gccapacity<br />
  -gcnew<br />
  -gcnewcapacity<br />
  -gcold<br />
  -gcoldcapacity<br />
  -gcpermcapacity<br />
  -gcutil<br />
  -gccause</td>
	</tr>
	<tr>
		<td>FGCT</td>
		<td>The accumulated time for full GC operations <span></span></td>
		<td>-gc<br />
  -gcold<br />
  -gcoldcapacity<br />
  -gcpermcapacity<br />
  -gcutil<br />
  -gccause</td>
	</tr>
	<tr>
		<td>GCT</td>
		<td>The total accumulated time for GC operations</td>
		<td>-gc<br />
  -gcold<br />
  -gcoldcapacity<br />
  -gcpermcapacity<br />
  -gcutil<br />
  -gccause</td>
	</tr>
	<tr>
		<td>NGCMN</td>
		<td>The minimum size of new area in KB</td>
		<td>-gccapacity<br />
  -gcnewcapacity</td>
	</tr>
	<tr>
		<td>NGCMX</td>
		<td>The maximum size of max area in KB <span>
		</span></td><td>-gccapacity<br />
  -gcnewcapacity</td>
	
	</tr><tr>
		<td>NGC</td>
		<td>The current size of new area in KB <span>
		</span></td><td>-gccapacity<br />
  -gcnewcapacity</td>
	
	</tr><tr>
		<td>OGCMN</td>
		<td>The minimum size of old area in KB</td>
		<td>-gccapacity<br />
  -gcoldcapacity</td>
	</tr>
	<tr>
		<td>OGCMX</td>
		<td>The maximum size of old area in KB</td>
		<td>-gccapacity<br />
  -gcoldcapacity</td>
	</tr>
	<tr>
		<td>OGC</td>
		<td>The current size of old area in KB <span>
		</span></td><td>-gccapacity<br />
  -gcoldcapacity</td>
	
	</tr><tr>
		<td>PGCMN</td>
		<td>The minimum size of permanent area in KB</td>
		<td>-gccapacity<br />
  -gcpermcapacity</td>
	</tr>
	<tr>
		<td>PGCMX</td>
		<td>The maximum size of permanent area in KB</td>
		<td>-gccapacity<br />
  -gcpermcapacity</td>
	</tr>
	<tr>
		<td>PGC</td>
		<td>The current size of permanent generation area in KB</td>
		<td>-gccapacity<br />
  -gcpermcapacity</td>
	</tr>
	<tr>
		<td>PC</td>
		<td>The current size of permanent area in KB</td>
		<td>-gccapacity<br />
  -gcpermcapacity</td>
	</tr>
	<tr>
		<td>PU</td>
		<td>The current usage of permanent area in KB <span></span></td>
		<td>-gc<br />
  -gcold</td>
	</tr>
	<tr>
		<td>LGCC</td>
		<td>The cause for the last GC occurrence <span></span></td>
		<td>-gccause</td>
	</tr>
	<tr>
		<td>GCC</td>
		<td>The cause for the current GC occurrence</td>
		<td>-gccause</td>
	</tr>
	<tr>
		<td>TT</td>
		<td>Tenuring threshold. If copied this amount of times in young
  area (S0 -&gt;S1, S1-&gt;S0), they are then moved to old area.</td>
		<td>-gcnew</td>
	</tr>
	<tr>
		<td>MTT</td>
		<td>Maximum Tenuring threshold. If copied this amount of times
  inside young arae, then they are moved to old area.</td>
		<td>-gcnew</td>
	</tr>
	<tr>
		<td>DSS</td>
		<td>Adequate size of survivor in KB<span>&nbsp; </span><span></span></td>
		<td>-gcnew</td>
	</tr>
</tbody></table>

<p>The advantage of <b>jstat</b> is that it can always monitor the GC operation data of Java applications running on local/remote machine, as long as a console can be used. From these items, the following result is output when <b>–gcutil</b> is used. At the time of GC tuning, pay careful attention to <b>YGC, YGCT, FGC, FGCT</b> and <b>GCT</b>.</p><p></p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">S0 &nbsp; &nbsp; &nbsp;S1 &nbsp; &nbsp; &nbsp; E &nbsp; &nbsp; &nbsp; &nbsp;O &nbsp; &nbsp; &nbsp; &nbsp;P &nbsp; &nbsp; &nbsp; &nbsp;YGC &nbsp; &nbsp;YGCT &nbsp; &nbsp; FGC &nbsp; &nbsp;FGCT &nbsp; &nbsp; GCT<br />0.00 &nbsp; &nbsp;66.44 &nbsp; &nbsp;54.12 &nbsp; &nbsp;10.58 &nbsp; &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp; 0.067 &nbsp; &nbsp;0.995<br />0.00 &nbsp; &nbsp;66.44 &nbsp; &nbsp;54.12 &nbsp; &nbsp;10.58 &nbsp; &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp; 0.067 &nbsp; &nbsp;0.995<br />0.00 &nbsp; &nbsp;66.44 &nbsp; &nbsp;54.12 &nbsp; &nbsp;10.58 &nbsp; &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp; 0.067 &nbsp; &nbsp;0.995</div><p></p><p></p><p></p>

<p>These items are important because they show how much time was spent in running GC.</p><p>In this example, <b>YGC</b> is 217 and <b>YGCT</b> is 0.928. So, after calculating the arithmetical average, you can see that it required about <i>4 ms</i> (0.004 seconds) for each young GC. Likewise, the average full GC time us <i>33ms</i>.</p><p>But the arithmetical average often does not help analyzing the actual GC problem. This is due to the severe deviations in GC operation time. (In other words, if the average time is <i>0.067 seconds</i> for a full GC, one GC may have lasted 1 ms while the other one lasted <i>57 ms</i>.) In order to check the individual GC time instead of the arithmetical average time, it is better to use <b>-verbosegc</b>.</p><h2>-verbosegc</h2><p><b>-verbosegc</b> is one of the JVM options specified when running a Java application. While <i>jstat</i> can monitor any JVM application that has not specified any options, <b>-verbosegc</b> needs to be specified in the beginning, so it could be seen as an unnecessary option (since jstat can be used instead). However, as <b>-verbosegc</b> displays easy to understand output results whenever a GC occurs, it is very helpful for monitoring rough GC information.</p>

<table>
<thead>
	<tr>
		<td></td>
		<td>jstat</td>
		<td>-verbosegc</td>
	</tr>
</thead>
<tbody>
	<tr>
		<td>Monitoring Target</td>
		<td>Java application running on a machine that can log in to a terminal, or a remote Java application that can connect to the network by using jstatd</td>
		<td>Only when -verbogc was specified as a JVM starting option</td>
	</tr>
	<tr>
		<td>Output information</td>
		<td>Heap status (usage, maximum size, number of times for GC/time, etc.)</td>
		<td>Size of ew and old area before/after GC, and GC operation time</td>
	</tr>
	<tr>
		<td>Output Time</td>
		<td>Every designated time</td>
		<td>Whenever GC occurs</td>
	</tr>
	<tr>
		<td>Whenever useful</td>
		<td>When trying to observe the changes of the size of heap area</td>
		<td>When trying to see the effect of a single GC</td></tr></tbody></table>

<p>The followings are other options that can be used with <b>-verbosegc</b>.</p><p></p><ul><li>-XX:+PrintGCDetails</li><li>-XX:+PrintGCTimeStamps</li><li>-XX:+PrintHeapAtGC&nbsp;</li><li>-XX:+PrintGCDateStamps (from JDK 6 update 4)</li></ul><p></p><p>If only <b>-verbosegc</b> is used, then <b>-XX:+PrintGCDetails</b> is applied by default. Additional options for <b>–verbosgc</b> are not exclusive and can be mixed and used together.</p><p>When using <b>-verbosegc</b>, you can see the results in the following format whenever a minor GC occurs.</p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="true" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[GC [&lt;collector&gt;: &lt;starting occupancy1&gt; -&gt; &lt;ending occupancy1&gt;, &lt;pause time1&gt; secs] &lt;starting occupancy3&gt; -&gt; &lt;ending occupancy3&gt;, &lt;pause time3&gt; secs]</div>

<table>
<thead>
	<tr>
		<td>Collector</td>
		<td>Name of Collector Used for minor gc</td>
	</tr>
</thead>
<tbody>
	<tr>
		<td>starting occupancy1</td>
		<td>The size of young area before GC</td>
	</tr>
	<tr>
		<td>ending occupancy1</td>
		<td>The size of young area after GC</td>
	</tr>
	<tr>
		<td>pause time1</td>
		<td>The time when the Java application stopped running for minor GC</td>
	</tr>
	<tr>
		<td>starting occupancy3</td>
		<td>The total size of heap area before GC</td>
	</tr>
	<tr>
		<td>ending occupancy3</td>
		<td>The total size of heap area after GC</td>
	</tr>
	<tr>
		<td>pause time3</td>
		<td>The time when the Java application stopped running for overall heap GC, including major GC</td>
	</tr>
</tbody>
</table>

<p>This is an example of <b>-verbosegc</b> output for <b>minor GC</b>:</p><p></p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">S0 &nbsp; &nbsp;S1 &nbsp; &nbsp; E &nbsp; &nbsp; &nbsp;O &nbsp; &nbsp; &nbsp;P &nbsp; &nbsp; &nbsp; &nbsp;YGC &nbsp; &nbsp;YGCT &nbsp; &nbsp;FGC &nbsp; &nbsp;FGCT &nbsp; &nbsp; GCT<br />0.00 &nbsp;66.44 &nbsp;54.12 &nbsp;10.58 &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp;0.067 &nbsp; &nbsp;0.995<br />0.00 &nbsp;66.44 &nbsp;54.12 &nbsp;10.58 &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp;0.067 &nbsp; &nbsp;0.995<br />0.00 &nbsp;66.44 &nbsp;54.12 &nbsp;10.58 &nbsp;86.63 &nbsp; &nbsp;217 &nbsp; &nbsp;0.928 &nbsp; &nbsp; 2 &nbsp; &nbsp;0.067 &nbsp; &nbsp;0.995</div>

<p>This is the example of output results after an <b>Full GC</b> occurred.</p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[Full GC [Tenured: 3485K-&gt;4095K(4096K), 0.1745373 secs] 61244K-&gt;7418K(63104K), [Perm : 10756K-&gt;10756K(12288K)], 0.1762129 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]</div>

<p>If a <a href="/blog/dev-platform/understanding-java-garbage-collection/#cms-gc" target="_self">CMS collector</a> is used, then the following CMS information can be provided as well.</p>

<p>As <b>-verbosegc</b> option outputs a log every time a GC event occurs, it is easy to see the changes of the heap usage rates caused by GC operation.</p>

<h2>(Java) VisualVM &nbsp;+ Visual GC</h2>

<p>Java Visual VM is a GUI profiling/monitoring tool provided by Oracle JDK.</p><p style="text-align: center;"><a href="/files/attach/images/220547/126/316/visual-vm.png" target="_self"><img src="/files/attach/images/220547/126/316/visual-vm.png" alt="Figure 1: VisualVM Screenshot." width="700" height="435" editor_component="image_link"/></a><br /></p><p style="text-align: center;"><b>Figure 1: VisualVM Screenshot.</b></p><p style="text-align: left;"><span class="Apple-style-span">Instead of the version that is included with JDK, you can download Visual VM directly from its website. For the sake of convenience, the version included with JDK will be referred to as Java VisualVM (jvisualvm), and the version available from the website will be referred to as Visual VM (visualvm). The features of the two are not exactly identical, as there&nbsp;</span><span class="Apple-style-span">are slight differences, such as when installing plug-ins. Personally, I prefer the Visual VM version, which can be downloaded from the website.</span></p><span style="color: windowtext; "><p>After running Visual VM, if you select the application that you wish to monitor from the window on the left side, you can find the "<i>Monitoring</i>" tab there. You can get the basic information about GC and Heap from this Monitoring tab.&nbsp;</p><p>Though the basic GC status is also available through the basic features of VisualVM, you cannot access detailed information that is available from either <b>jstat</b> or <b>-verbosegc</b> option.&nbsp;</p>

<p>If you want the detailed information provided by jstat, then it is recommended to install the Visual GC plug-in.&nbsp;</p><p>Visual GC can be accessed in real time from the <i>Tools</i> menu.</p>

<p style="text-align: center;`"><img src="/files/attach/images/220547/126/316/visual-gc-installation.png" alt="Figure 2:&amp;nbsp;Viusal GC Installation Screenshot." width="427" height="363" editor_component="image_link"/></p>

<p style="text-align: center;"><b>Figure 2:&nbsp;Viusal GC Installation Screenshot.</b></p><p>By using Visual GC, you can see the information provided by running <b>jstatd</b> in a more intuitive way. &nbsp;</p><p style="text-align: center;"><a href="/files/attach/images/220547/126/316/visual-gc-execution.png" target="_self"><img src="/files/attach/images/220547/126/316/visual-gc-execution.png" alt="Figure 3:&amp;nbsp;Visual GC execution screenshot." width="700" height="445" editor_component="image_link"/></a><br /></p><p style="text-align: center;"><b>Figure 3:&nbsp;Visual GC execution screenshot.</b></p><h2>HPJMeter</h2><p><a href="https://h20392.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=HPJMETER" target="_self">HPJMeter</a> is convenient for analyzing <b>-verbosegc</b> output results. If Visual GC can be considered as the GUI equivalent of <i>jstat</i>, then HPJMeter would be the GUI equivalent of <i>-verbosgc</i>. Of course, GC analysis is just one of the many features provided by HPJMeter. HPJMeter is a performance monitoring tool developed by HP. It can be used in HP-UX, as well as Linux and MS Windows.</p><p>Originally, a tool called <b>HPTune</b>&nbsp;used to provide the GUI analysis feature for <b>-verbosegc</b>. However, since the HPTune feature has been integrated into HPJMeter since version 3.0, there is no need to download HPTune separately.</p><p>When executing an application, the <b>-verbosegc</b> output results will be redirected to a separate file.</p><p>You can open the redirected file with HPJMeter, which allows faster and easier GC performance data analysis through the intuitive GUI.</p></span>

<p style="margin-top: 7px; margin-right: 0px; margin-bottom: 7px; margin-left: 0px; text-align: center;"><a href="/files/attach/images/220547/126/316/hpjmeter.png" target="_self"><img src="/files/attach/images/220547/126/316/hpjmeter.png" alt="Figure 4:&amp;nbsp;HPJMeter." width="700" height="474" editor_component="image_link"/></a></p>

<p style="text-align: center;"><b>Figure 4:&nbsp;HPJMeter.</b></p>

<h2>What is the Next Article About?</h2>

<p>In this article I focused on <i>how to monitor GC operation information</i>, as the preparation stage for GC tuning. From my personal experience, I suggest using <b>jstat</b> to monitor GC operation, and if you feel that it takes too lmuch time to execute GC, then try <b>-verbosegc</b> option to analyze GC. The general GC tuning process is <i>to analyze the results after applying the changed GC options</i> after the <b>-verbosegc</b> option has been applied based on the analysis. In the next article, we will see the best options for executing GC tuning by using real cases as our examples.</p><p>By Sangmin Lee, Senior Engineer at Performance Engineering Lab, NHN Corporation.</p>]]></description>
                        <pubDate>Wed, 28 Mar 2012 18:26:49 +0900</pubDate>
                        <category>Java</category>
                        <category>Garbage Collection</category>
                        <category>performance</category>
                        <category>JVM</category>
                        <category>NHN</category>
                        <category>tuning</category>
                        <category>analysis</category>
                        <category>monitoring</category>
                                </item>
        										        <item>
            <title>CUBRID Has Joined Google+</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-life/cubrid-has-joined-google-plus/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-life/cubrid-has-joined-google-plus/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-life/cubrid-has-joined-google-plus/#comment</comments>
                                    <description><![CDATA[<p><i>Using Google+? Add <a href="https://plus.google.com/b/115924035309696499466/115924035309696499466/posts" target="_self">CUBRID</a> to your circles. You will get the latest news about CUBRID, the most optimized database for Web applications, as well as <a href="/blog/categories/dev-platform/" target="_self">great tutorials</a> our top engineers write for fellow developers like those we have already posted on&nbsp;<a href="/blog/tags/Java/" target="_self">Java</a>, <a href="/blog/tags/Android/" target="_self">Android</a>, <a href="/blog/tags/Git/" target="_self">Git</a>, and&nbsp;<a href="/blog/tags/NoSQL/" target="_self">NoSQL</a>.</i></p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/358/326/cubrid-google-plus-profile.png" alt="cubrid-google-plus-profile.png" width="500" height="346" editor_component="image_link"/></p><p>We have already created <a href="https://www.facebook.com/cubrid" target="_self">CUBRID Facebook</a> page as well as <a href="/twitter.com/CUBRID" target="_self">@CUBRID Twitter</a> account to communicate with our users by answering to their questions and posting very detailed tutorials, announcing new CUBRID releases as well as praising our <a href="/blog/cubrid-appstools/jooq-java-object-oriented-querying-now-supports-cubrid-database/" target="_self">distinguished users</a>.</p><p>We hope you will add&nbsp;<a href="https://plus.google.com/b/115924035309696499466/115924035309696499466/posts" target="_self" style="font-style: italic; ">CUBRID</a>&nbsp;to your Google+ Circles because we would love to connect with you there. You can talk directly to CUBRID core developers, learn about the latest&nbsp;improvements in CUBRID Database, and stay up to date with the important news from our open source database community.</p>

<p style="text-align: center;"><span style="color:#3D9400"><b>Join us at Google+!</b></span></p>

<div style="text-align: center;">
<g:plus href="https://plus.google.com/115924035309696499466" rel="publisher" width="223" height="131" theme="light"></g:plus>
</div>]]></description>
                        <pubDate>Fri, 13 Apr 2012 17:04:26 +0900</pubDate>
                        <category>Google+</category>
                        <category>SNS</category>
                                </item>
        										        <item>
            <title>CUBRID support comes in Hibernate 4.0.0</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/news/cubrid-support-comes-in-hibernate-4-0-0/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/news/cubrid-support-comes-in-hibernate-4-0-0/</guid>
                        <comments>http://www.cubrid.org/blog/news/cubrid-support-comes-in-hibernate-4-0-0/#comment</comments>
                                    <description><![CDATA[<p>In addition to <a title="CUBRID is coming to CodeIgniter PHP Framework" href="http://blog.cubrid.org/news/cubrid-is-coming-to-codeigniter-php-framework/">CodeIgniter</a>, there is one more good news for CUBRID users. We are making friends with Hibernate!</p>

<p>The story behind Hibernate integration is that at NHN we have a large service running on Hibernate. However, unlike other cases, in this service we use CUBRID as a back-end database engine. So for several years we have been successfully using this combination in production.</p>

<p>Last month, though, we decided to allocate some resources and contact the Hibernate team and commit the patch.&nbsp;Fortunately, there were not serious reasons on Hibernate side which would keep our code away from their master branch thanks to the way Hibernate works.</p>

<p>Since the framework is implemented in Java, it connects to the database server through the JDBC driver, which provides standard Java methods to manage a database. So, ideally Hibernate will work with any database which provides a JDBC driver with a small exception. There has to be a way to tell Hibernate if certain database features, implemented in the framework, are supported by the DBMS. In other words DB vendors need to introduce the <em>Dialect</em> which the database speaks in.</p>

<p>Cutting to the chase, we have committed the CUBRIDDialect class to Hibernate <a href="https://github.com/hibernate/hibernate-orm/pull/154" target="_self">master</a> and <a href="https://github.com/hibernate/hibernate-orm/pull/153" target="_self">3.6</a> repositories on GitHub. Yesterday, the Hibernate team released the second Code Release&nbsp;of&nbsp;its new 4.0.0 branch.&nbsp;I have just checked its source code and can confirm that CUBRID dialect is included. Congratulations!</p>

<p>I do not know how many more CRs are planned, but if you wish to use Hibernate with CUBRID now, feel free to download the latest version of its 4.0.0 line from <a href="http://hibernate.org/downloads">http://hibernate.org/downloads</a>.</p>

<p>If you notice any weird behavior when working with CUBRID, please report your issues to our <a href="http://jira.cubrid.org/">http://jira.cubrid.org</a> issue tracker. Any other questions can be posted at our <a title="CUBRID Forum" href="/forum">CUBRID Forum</a>.</p>]]></description>
                        <pubDate>Sat, 03 Sep 2011 07:54:44 +0900</pubDate>
                        <category>News</category>
                        <category>CUBRID Apps&amp;Tools</category>
                        <category>JDBC</category>
                        <category>Java</category>
                        <category>Hibernate</category>
                        <category>Framework</category>
                        <category>GitHub</category>
                                </item>
        										        <item>
            <title>How SQL UPDATE is performed in CUBRID RDBMS</title>
            <dc:creator>Donghyun Lee</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/how-sql-update-is-performed-in-cubrid-rdbms/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/how-sql-update-is-performed-in-cubrid-rdbms/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/how-sql-update-is-performed-in-cubrid-rdbms/#comment</comments>
                                    <description><![CDATA[<p>The internals of an RDBMS is extremely profound and sensitive. When updating a record in the table, not only the size of columns to be updated&nbsp;affects the performance&nbsp;but also the size of the record itself.  Updating a variable-length column is less favorable than updating a fixed-length column in terms of performance, and when updating a variable-length column, you need to <i>change the <b>unfill_factor</b> value</i> and <i>adjust the percentage of disk space</i>.</p><p>In this article, I will explain why these details affect an UPDATE performance, and what happens inside CUBRID when an UPDATE query is executed. My story will be based on the latest version of CUBRID as of today 8.4.1. 
</p><h2>UPDATE in RDBMS</h2>

<p>Let's make an analogy between the process that implements an UPDATE query in RDBMS and the process of selling products in a shopping mall.</p>

<table style="margin:0 auto">
<thead>
<tr>
<td>Shopping mall</td>
<td>RDBMS</td>
</tr>
</thead>
<tbody><tr><td>Storage</td><td>Disk</td></tr>
<tr><td>Shelf</td><td>Memory Buffer</td></tr></tbody></table>

<p>At a shopping mall the employee keep frequently bought products on the shelves and less frequently purchased products in the main storage. When customers come, they can buy the products available on shelves quickly without waiting. For products not available on the shelves, they have to wait while the shopping mall employees go and retrieve them from the storage.&nbsp;It is the same in RDBMS.&nbsp;To have fast access to the data, you need to put frequently requested data in a memory buffer. How and what products are displayed on the shelves will have a profound impact on the shopping mall's sales. Likewise, depending on which data is in the memory buffer, it will have a decisive effect on RDBMS.</p><p>In order to improve performance, RDBMS handles data input/output by page (the default value in CUBRID is <b>16KB</b>). Operations for the memory buffer used for cache are also processed by pages.
</p><p>There could be a shortage of space if too many products are displayed on the shelf.  Suppose you want to remove slow-selling items off the shelves and display other more frequently sold products. However, the latter ones are too big to be displayed. <b>What should you do?</b> You will have to move products around on the shelf to allocate more space for big ones.</p><blockquote class="q2"><p><b>Which method should you use if you do not want to rearrange a page when the new data to be UPDATED from RDBMS is bigger than the old record?</b></p></blockquote><p>Maybe the employees at the shopping mall could display products on the shelf all together. It would be effective to divide areas but it is impossible in RDBMS. In RDBMS, reading and writing can occur in one record at the same time, or there could be a race in limited buffer space.   Therefore, you should be able to access a record exclusively by using <b>record locking</b>.</p><blockquote class="q2"><p><b>How do we actually make this work?</b></p></blockquote>
<p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="true" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">UPDATE athlete SET name = 'Cheolsu Kim' WHERE code = '10980';</div><p></p><p>The above SQL implementation process can be summarized in the flowchart below:</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/implementation-process-flowchart-for-update-query.png" alt="implementation-process-flowchart-for-update-query.png" width="535" height="319" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 1: Implementation process flowchart for UPDATE query.</strong></p><p style="text-align: left;">To be precise, we should also express the process of <i>SQL parsing</i>, <i>SQL optimization</i>, <i>transaction process</i>, <i>data locking</i>, <i>data correction</i>, <i>data storing</i>, <i>operation logging</i>, and <i>operation restoration</i>.  However, this article will focus only on <b>what happens in memory buffer and disk while updating</b>. 
</p><h2>Index Navigation</h2><p>The first thing to be done is to <i><b>find the record we need to update</b></i>. If the conditions used in the corresponding query can use index, then we can use index navigation.</p><p>If the details of the our record are in the memory buffer, use them as they are.  If the record is not found in the memory buffer, we need to read it from the disk and transfer it to the memory buffer.  This process is called <b>FIX</b>.
</p><p>In CUBRID,&nbsp;<b>index</b> is composed of a <b>B+ tree</b> (for details refer to <a href="/cubrid_query_tuning" target="_self">CUBRID Query Tuning Techniques</a> and <a href="/cubrid_covering_index" target="_self">What is Covering Index in CUBRID 8.4.0?</a>). Generally speaking, a <b>B+ tree</b> stores the location (VPID) of <i>previous</i> and <i>next</i> key nodes in a&nbsp;<b>non-leaf</b> node while the disk location of the actual data which corresponds to the key is stored in a <b>leaf</b> node.  Therefore data search process is affected by the type of a B+ tree configuration.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/storage-structure-of-b+tree.png" alt="storage-structure-of-b+tree.png" width="741" height="396" editor_component="image_link"/></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 2: Storage structure of a B+ tree index.</strong></p><p>Sometimes the size of a column (like text) can be bigger than a page (16KB).  In this case you need a separate storage other than the node of a B+ tree.  Therefore, you might have to allocate a separate storage space except the B+ tree when searching for data. 
</p><p>Further I will explain about which index configuration is likely to cause the <b>overflow key file</b> or <b>overflow OID</b>&nbsp;issues when UPDATE-ing a record.
</p><h3>Overflow Key</h3><p>First, let's look at a very large node that configures index.</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">CREATE INDEX idx_history ON athlete(history);<br />UPDATE athlete<br />SET gold = 3<br />WHERE history = $history_string;</div><p></p>
<p>If <b>history</b> field data used by key is roughly 100KB, it will be greater than a page (16KB), a unit that stores regular data.  This is called an <b>overflow key</b>, and you cannot save the key value to a page.  In a node, you should store ID (OFID, <b>Overflow File ID</b>), which refers to a file that stores the key value.</p><p>As CUBRID manages data by page, it is burdensome if data is divided into several pages, as many memory copies (<b>memcpy</b>) are needed to configure a single piece of data.  Hence, it is recommended to consider the size of a key so that it can be stored in one page if possible. 
</p><h3>Overflow OID</h3><p>Now let's look at a situation in which keys are overlapped.</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">CREATE INDEX idx_gender ON athlete(gender);<br />UPDATE FROM athlete<br />SET gender_type = 'Male'<br />WHERE gender = 'M'</div><p></p>
<p>Assume&nbsp;<b>gender</b>&nbsp;column is indexed. Low-selectivity of the <b>gender </b>field&nbsp;(only two values "M" and "F", or&nbsp;<span style="font-family: monospace; ">DISTINCT(column)</span> is low) may result in&nbsp;many OIDs being stored in the same node in B+ tree for the same index key.&nbsp;If space necessary for storing OID is bigger than a page by 1/4, it will be stored in a separate <b>Overflow OID</b> (OOID) page. If the number of separate overflow pages increases, it would affect the performance as there would be a burden to navigate between these additional links.</p><p>The following is a structure of a B+ tree in case&nbsp;<b>overflow files</b>&nbsp;and&nbsp;<b>overflow OID pages</b>&nbsp;exist.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/storage-structure-of-ofid-and-ooid.png" alt="storage-structure-of-ofid-and-ooid.png" width="737" height="280" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 3: A storage structure of OFID and OOID.</strong></p><h3>Modifying the Column Value</h3><p>This process finds the record to be updated and modifies the necessary column data of the record. The following flowchart summarizes this process:</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/data-update-flowchart.png" alt="data-update-flowchart.png" width="248" height="348" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 4: Data update flowchart.</strong></p><p>Since RDBMS implements read and write operations in <b><i>pages</i></b>, you will need to read or write more than one pages.  Data stored in the memory can be read/written faster than the data stored on a disk, thus you should minimize disk I/O operations by maximizing the memory. 
</p><p>To do this, you can use a <b>memory buffer</b>, which is an intermediate storage space. &nbsp;As shown in the above Figure 4, first, check if the necessary data is in the memory buffer. If there is no data, load it to the memory buffer from the disk (DB Volume).  Then update the data in the memory. When the data is updated, the data to be modified is recorded in logs, and, finally, it is recorded to the database volume (disk) at the checkpoint. 
</p><h2>Memory and Disk Management</h2><p>The following figure summarizes the policy and main tasks used for memory and disk management.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/work-that-occurs-when-storing-update-data.png" alt="work-that-occurs-when-storing-update-data.png" width="717" height="547" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 5: Work that occurs when storing updated data.</strong></p><h3>Page Management Policy</h3><h4>LRU (Least-Recently Used)</h4><p>In order to effectively use the limited buffer size and maintain recently used data, remove the data which has not been used for a long time and free up the space.  This is a memory method used by the <b>STEAL</b> policy.
</p><h3>Tasks of Buffer Administrator</h3><h4>FIX</h4><p>The task acquires a latch for a buffer in competition with other transactions when reading a page from a disk using a memory buffer.  Therefore, you cannot use different transactions while acquiring a latch for a buffer to be used in your transaction. If there is a corresponding page in a buffer, a page is not loaded from a disk (database volume). 
</p><h4>UNFIX</h4><p>This is a different concept from FIX in a way that the task is for a page that is no longer used in a transaction.  It is not always the case that an UNFIXed page is flushed to a disk. 
</p><h4>FLUSH</h4><p>In this task you will write a DIRTY page in a buffer to a disk.  As you have to write a log file&nbsp;(WAL - Write-Ahead Log)&nbsp;to a disk, just before executing the task a race can occur in which two or more files write in the same log file.</p><h3>Logging Policy to Restore Failure or Rollback</h3><h4>WAL (Write-Ahead Logging)</h4><p>Write-Ahead Logging is a policy to enable restoration upon system failure, i.e. <i><b>always write</b></i> UNDO/REDO logs to a disk <b><i>before</i></b> writing the data page.  <b>UNDO</b> includes the data before UPDATE and <b>REDO</b> includes the new data after UPDATE. 
</p><p>You can use STEAL/NO STEAL, FORCE/NO FORCE policies to specify when to reflect the page stored in a memory buffer to a disk. 
</p><h4>STEAL/NO STEAL</h4><p>When a transaction attempts to use a memory buffer, the <b><span style="font-family: monospace; ">STEAL</span></b> policy flushes the Least Recently Used (LRU) <i>dirty</i> pages and frees up the memory buffer.  To use the STEAL policy, you need UNDO logging in order to recover old data when you rollback a transaction. 
</p><p>In contrast, the <b><span style="font-family: monospace; ">NO STEAL</span></b> policy keeps a DIRTY page in a buffer until a transaction is completed.  Therefore, there should be enough buffer space to keep all pages that have been changed by all transactions in progress. 
</p><h4>FORCE/NO FORCE</h4><p>The <span style="font-family: monospace; "><b>FORCE</b></span> policy reflects all pages updated by a transaction to a database volume when commit is called. Using the FORCE policy affects performance, as disk write has to be carried out every time a transaction commits.  If a page has to be <i>corrected</i> 20 times by several transactions in a brief period of time, the disk also needs to be written to 20 times. 
</p><p>The <span style="font-family: monospace; "><b>NO FORCE</b></span> policy does not necessarily reflect all pages renewed by a transaction during a commit process.  The costs for rewriting a page could be reduced, if other transactions are renewing the same page while commit is not reflected to a database volume. However, to ensure data changes by a successfully committed transaction, REDO logging is necessary in the event of a system failure. 
</p><p>The <b><span style="font-family: monospace; ">NO STEAL</span></b> and <b><span style="font-family: monospace; ">FORCE</span></b> policies will be the easiest implementation, but their performance is the worst.  As the <b><span style="font-family: monospace; ">STEAL</span></b> and  <b><span style="font-family: monospace; ">NO FORCE</span></b> policies are the best, most databases including CUBRID are implemented via these policies. For this reason both UNDO logging and REDO logging are necessary, and the entire record should be logged not just the column to UPDATE.  When UNDO logging, the record before the change is stored <i>as-is</i> and the record after the change is <i>compressed</i> and stored when REDO logging. 
</p><p>You must note that a big record size will affect logging, even if the size of column to UPDATE is small.  If there are a lot of records that are very big and the number of columns to UPDATE frequently is small, it is preferable to gather these UPDATE-able columns and create a separate table for them. This is recommended only considering the size of logging records. 
</p><h2>Page Storage Structure</h2><p>Now let's learn about <b>how a page is stored depending on the size of data to UPDATE</b>.  The following figure shows the basic structure where a page is stored in the record:
</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/record-storage-structure-inside-page.png" alt="record-storage-structure-inside-page.png" width="569" height="164" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 6: Record storage structure inside a page.</strong></p><p>When a new value is entered, <i>records are assigned from the front of a page</i> while <i>slots are assigned from the end of a page</i> in the opposite direction. One record consists of a header (<b>header</b>), fixed-length columns (<b>Fix Col</b>), and variable-length columns (<b>Var Col</b>).  The following explains each component. 
</p><ul><li><b>page header</b>: Stores the following information&nbsp;about total slots within a page</li><ul><li>a number of slots and records</li><li>the size of total extra space and contiguous extra space</li><li> the initial offset of contiguous space</li><li> transaction ID</li><li> etc.</li></ul><li><b>heap page header</b>: Stores initial record location and schema information location.
</li><li><b>record</b>: Stores a record value.
</li><li><b>slot</b>: Stores information about record location (offset, length).
</li></ul><p>If there is a variable-length column in a record, the size of the record to UPDATE may be changed.  If the record to UPDATE is smaller than the existing size, data can be UPDATEd in the same location. However, if the size is bigger, assign the record to UPDATE in the same page, and the existing slot indicates the record to UPDATE.  If there is no space in the same page to UPDATE a new record, a separate page will be assigned as shown in the following figure, and the existing record indicates a new record.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/structure-of-record-storage-when-space-update.png" alt="structure-of-record-storage-when-space-update.png" width="563" height="320" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 7: The structure of record storage when space to UPDATE in the existing page is insufficient.</strong></p><p>If the size of a record to UPDATE is bigger than a page, data is divided and stored by page as shown in the following figure, and the page that stored the previous data indicates the page that stored renewed data.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/structure-of-record-storage-when-record-is-big.png" alt="structure-of-record-storage-when-record-is-big.png" width="575" height="269" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 8: The structure of a record storage when the record to UPDATE is bigger than a page.</strong></p><p>When writing data in this case, data should be split into several pages, and to read, the split pages should be loaded in a series of memory, which may negatively affect the performance. 
</p><h2>Exclusive Record Lock</h2><p>To this point we have explored <b>how CUBRID uses system memory and disk when UPDATE query is requested</b>. Now I will explain <b>how to manage records within the corresponding range when executing an UPDATE query</b>. 
</p><p>Generally, a&nbsp;<b><span style="color: rgb(0, 158, 37); ">shared lock</span></b> is used to search for a specific record to <i><b>allow other transactions to see [SELECT] the same record you are currently navigating</b></i>. For <span style="font-family: monospace; ">INSERT</span>, <span style="font-family: monospace; ">UPDATE</span>, or <span style="font-family: monospace; ">DELETE</span>, an <b><span style="color: rgb(0, 158, 37); ">exclusive lock</span></b> is used to<b><i> block access from other transactions</i></b>. 
</p><p>In the searching process using&nbsp;<b>WHERE</b> condition, however, you must use an&nbsp;<b><span style="color: rgb(0, 158, 37); ">update lock</span></b> instead of <b>shared lock</b> when acquiring the lock for the record in the target range of <span style="font-family: monospace; ">UPDATE</span>. You also need to <i>acquire the <b>key of the record</b></i> in operation and the <b><i>lock for the next key</i></b> to block your operating range from other transactions.
</p><p>We will describe <b>why an additional update lock is necessary besides exclusive lock during UPDATE</b>, and <b>why key locking is needed</b>. 
</p><h3>Update Lock</h3><p>The following explains lock acquisition/release for UPDATE execution. 
</p><ul><li>Request UPDATE query with the WHERE condition to the database server.</li><li><b><i>Acquire update lock</i></b> while searching for the record with the corresponding range condition.&nbsp;
</li><li>In this case, <b><i>acquire the key lock</i></b> for the following corresponding key in the WHERE condition range.
</li><li>While executing actual data <span style="font-family: monospace; ">UPDATE</span>, <b><i>convert update lock to exclusive lock</i></b>.
</li><li>Commit transactions and <b><i>release all acquired locks</i></b>.
</li></ul><p>The action of an <b>update lock</b> can be explained as:</p><blockquote class="q2"><p><b>as this is the only transaction authorized to UPDATE until the UPDATE transaction is completed, other transactions cannot not UPDATE.</b></p></blockquote><p>Another transaction <i><b>can</b></i> acquire an update lock on a transaction that has a record with <i>shared lock</i>.  However, if a transaction has acquired <i>update lock</i>, another transaction <i><b>cannot</b></i> obtain <i>shared lock</i>. 
</p><p>Concurrency may decrease if an <i>exclusive lock</i> of the record to UPDATE can be obtained immediately, and thus using shared lock seems to be a better option while searching for a target by condition.  <b>Why do we have to use an update lock instead of shared lock?</b> The reason is to <i><b>minimize deadlock</b></i>.  For better understanding, let's look at the following table, which has no update lock.</p>

<table style="margin:0 auto">
	<tbody><tr><td>Transaction 1</td><td>shared lock1 (Record A)</td></tr><tr><td>Transaction 2</td><td>shared lock2 (Record A)</td></tr><tr><td>Transaction 1</td><td>exclusive lock1 (Record A);<br />Standby</td></tr><tr><td>Transaction 2</td><td>exclusive lock1 (Record A);<br />Standby</td></tr></tbody></table>

<p>The situation above is the one in which <i>Transactions 1</i> and <i>2</i> of the same <i>Record A</i> acquired the&nbsp;<i>shared lock</i>, and they are about to <i>upgrade the lock to exclusive lock</i>.  However, they <i>both are waiting for the other transaction to free shared lock</i>; that is, <i>they are in deadlock</i>. <b>What would happen if there is an update lock?
</b></p>

<table style="margin:0 auto">
	<tbody><tr><td>Transaction 1</td><td>update lock1 (Record A);<br />Navigation</td></tr><tr><td>Transaction 2</td><td class="">update lock2 (Record A);<br />Standby</td></tr><tr><td>Transaction 1</td><td class="">exclusive lock1 (Record A);<br />UPDATE;<br />lock release</td></tr>
<tr><td>Transaction 2</td><td class="">update lock2 (Record A);<br />Navigation;<br />exclusive lock2 (Record A);<br />UPDATE;<br />lock release</td></tr></tbody></table>

<p><i>Transaction 1</i> has acquired an <i>update lock</i> and <i>Transaction 2</i> is in the <i>standby mode</i> to obtain an <i>update lock</i>. <i>Transaction 1</i> changes the <i>update lock</i> to <i>exclusive lock</i>, UPDATEs <i>Record A</i> and releases the lock.  Transaction 2 acquires the update lock2, which was in a standby mode, and thus it can execute UPDATE.  When the update lock is introduced, you can avoid some of the deadlock effects caused by UPDATE.
</p><p>The following deals with specific examples of the situations above.  <b><i>Automatic commit</i></b> mode is released and <b><i>isolation level is 4</i></b> (REPEATABLE READ SCHEMA, READ COMMITTED INSTANCES).</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">create table t1(id int, num int);<br />create unique index idx_t1_id on t1(id);<br />insert into t1 values (10,10), (20,20), (40,40), (80, 80);<br />commit;</div><br /><p></p>

<table style="margin:0 auto">
	<tbody><tr><td>Transaction 1</td><td class=""> Execution (update ... where id = 40;)</td></tr><tr><td>Transaction 2</td><td class="">Standby (update ... id = 40;); Standby</td></tr><tr><td class="">Transaction 1</td><td class="">commit;</td></tr><tr><td class="">Transaction 2</td><td class="">Execution (update ... where id = 40;)</td></tr><tr><td class="">Transaction 2</td><td class="">commit;</td></tr></tbody></table>

<p>When a transaction is acquiring an <i>update lock</i>, other transactions <i>cannot</i> UPDATE or DELETE the corresponding record. Therefore, if you use an update lock and access the same record above, you can avoid deadlock resulting from UPDATE.  An update lock is used not only for UPDATE, but also for DELETE tasks with the WHERE condition that uses index.
</p><h3>Key Lock</h3><p>An update lock can be obtained even when the record to UPDATE is in the shared lock with other transactions; however, two or more transactions cannot be acquired at the same time. 
</p><p><b>For data consistency, </b><b>update lock alone is insufficient</b>. Let's consider the following example.</p>

<table style="margin:0 auto">
	<tbody><tr><td>Transaction 1</td><td class="">delete table where id = 1</td></tr><tr><td>Transaction 2</td><td class="">insert into t1 (id) values (1)</td></tr><tr><td>Transaction 2</td><td class="">       commit</td></tr><tr><td>Transaction 1</td><td class="">rollback</td></tr></tbody></table>

<p>There are many models that can be used to handle the request above, and approach methods vary depending on RDBMS. 
</p><p>CUBRID 2008 R4.1 places the INSERT task of Transaction 2 in a standby mode. However, Transaction 1 cannot put Transaction 2's tasks in the standby mode by using an update lock as the data of the corresponding key will be deleted from the B+tree when executing DELETE. This problem can be solved by using a <span style="color: rgb(0, 158, 37); "><b>key lock</b></span>.
</p><p>When performing DML tasks, a <b>key lock</b> <b><i>acquires lock authority of the record</i></b> indicated by the next key of the record for processing. If table locking is executed without obtaining a key lock, it will deteriorate concurrency; thus, a lock to a certain area should be obtained to ensure maximum concurrency.
</p><p>Typical example of using key locks is a <b>unique index</b>.  When performing DML tasks, you should obtain a key lock for the record indicated by the next key of the corresponding record and the target record, to ensure there are no DML tasks by other transactions within the range. 
</p><p>Let's learn about the operating process of key locks with the following example:  Automatic commit mode is released.</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">create table t1 (id int, num int);<br />create unique index idx_t1_id on t1(id);<br />insert into t1 values (10,10), (20,20), (40,40), (80, 80);<br />commit;</div><br /><p></p>

<table style="margin:0 auto">
	<tbody><tr><td class="">Transaction 1</td><td class=""> update t1 set num=400 where id=40;</td></tr><tr><td class="">Transaction 2</td><td class=""><p><span style="font-size:9pt"><span style="font-family:Arial">insert into t1 values (30, 30);&nbsp; Standby</span><span style="font-family:Arial">…</span><span style="font-family:Arial"> rollback;</span></span></p></td></tr><tr><td class="">Transaction 2</td><td class=""><p><span style="font-size:9pt"><span style="font-family:Arial">delete from t1 where id=20;&nbsp; Standby</span><span style="font-family:Arial">…</span><span style="font-family:Arial"> rollback;</span></span></p></td></tr><tr><td class="">Transaction 2</td><td class=""><p><span style="font-size:9pt"><span style="font-family:Arial">insert into t1 value (70, 70);&nbsp; Standby</span><span style="font-family:Arial">…</span><span style="font-family:Arial"> rollback;</span></span></p></td></tr><tr><td class="">Transaction 2</td><td class=""><p><span style="font-size:9pt"><span style="font-family:Arial">delete from t1 where id=80;&nbsp; Standby</span><span style="font-family:Arial">…</span><span style="font-family:Arial"> rollback;</span></span></p></td></tr><tr><td class="">Transaction 2</td><td class=""><p><span style="font-size:9pt"><span style="font-family:Arial">update t1 set num=444 where id=80;&nbsp; Standby</span><span style="font-family:Arial">…</span><span style="font-family:Arial">rollback;</span></span></p></td></tr></tbody></table>

<ul><li>When Transaction 1 executes UPDATE of the id=40 record, the transaction will acquire the key lock for the id=40 key and id=80, the next key. In this case, other transactions within the range cannot INSERT, UPDATE, or DELETE new records.
</li><li>For Transaction 2 to INSERT the id=30 record, it should acquire the key lock for id=40; as Transaction 1 already acquired the key lock for id=40, the work is in standby mode. 
</li><li>As Transaction 1 already acquired the key lock for id=40 and id=80, all other tasks, which require the work with these keys, are all in standby mode.&nbsp; 
</li></ul><p>It is likely that other transactions can be in standby mode because of key lock. The more indexes you have on a column you plan to UPDATE, the occurrence of key lock&nbsp;may increase which results in a greater negative effect on UPDATE performance. Thus, we recommend that you remove index for the corresponding columns, considering both SELECT and UPDATE performance.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/key-lock-related-scenario.png" alt="key-lock-related-scenario.png" width="692" height="274" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 9: Key lock related scenario about records being updated.</strong></p><p>Considering the occurrence of deadlock between indexes due to key lock, we recommend that you retry the corresponding task. In the following scenario, we will learn about <b>deadlocks resulting from key lock</b>. Deadlock may occur under the assumption that Transaction 1 and 2 are implemented at the same time.</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">create table t1(id int, num int);<br />create unique index idx_t1_id on t1(id);<br />insert into t1 values (10,10), (20,20), (40,40), (80, 80);commit;</div><br /><p></p>

<table style="margin:0 auto">
	<tbody><tr><td>Transaction 1</td><td> update t1 set num = 40 where id = 1 using index pk_t1_id; (pk)</td></tr><tr><td>Transaction 2</td><td> update t1 set id = 30 where num = 7 using index i_t1_num;&nbsp; (idx)</td></tr></tbody></table>

<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/dead-lock-scenario-caused-by-key-lock.png" alt="dead-lock-scenario-caused-by-key-lock.png" width="224" height="111" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 10: Deadlock scenario caused by key lock.</strong></p><p>Transaction 1 attempts to UPDATE the column num of id=1 record and <b>obtains the key lock</b> for id=1 and id=5 as well as the <b>exclusive lock</b> for record  (1,9). In this case, Transaction 2 attempts to UPDATE the column id, which is num = 7, and <b>acquires the key lock</b> for num=7 and num=9 as well as the <b>exclusive lock</b> for record (5 and 7).
</p><p>Transaction 1 needs the key lock for index idx 9 to UPDATE the column num of id=1 record but Transaction 2 has already acquired the corresponding lock. While Transaction 2 needs the key lock for index pk 5 to UPDATE the column id of num=9 record, Transaction 1 has already acquired the corresponding lock. That is, deadlock has occurred.
</p><p><b>Key lock</b> has <b>key shared lock</b> and <b>key exclusive lock</b>. The lock that the <span style="font-family: monospace; ">INSERT</span> task acquires for the next key is <b>key shared lock</b>, and the lock that <span style="font-family: monospace; ">UPDATE</span>d or <span style="font-family: monospace; ">DELETE</span>d tasks will acquire for the next key is <b>key exclusive lock</b>.  When UPDATE or DELETE is working on the record of a specific range, other transactions must not change the record within the corresponding range; this is to allow INSERT by other transactions into the key lock range of the next location during INSERT operation. Let's examine the following figure:
</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/482/328/key-lock-related-scenario-for-record-being-inserted.png" alt="key-lock-related-scenario-for-record-being-inserted.png" width="380" height="231" editor_component="image_link"/><br /></p><p style="text-align: center;"><strong style="font-family: Arial; font-size: 9pt; ">Figure 11: Key lock related scenario for record being INSERTed.</strong></p><p>When Transaction 1 INSERTs <span style="font-family: monospace; ">id = 90</span> record, it acquires the <b>key shared lock</b> for <span style="font-family: monospace; ">id = 100</span>, the next key. When Transaction 2 INSERTs <span style="font-family: monospace; ">id = 95</span> record, it acquires the <b>key shard lock</b> for <span style="font-family: monospace; ">id = 100</span>, which is also the next key.  Lock sharing by transactions that are different from one another on the same key <span style="font-family: monospace; ">id = 100</span> is possible because key lock is acquired in key shared lock mode.
</p><h2>In Conclusion</h2><p>In this article we have observed <b>the events that occur in the memory and disk storage structure</b> during UPDATE of data in CUBRID and <b>how to obtain locks</b> so as to block other transactions from the record within the UPDATE range. 
</p><p><b>It is a mistake to think that the processing costs will be small</b> <i>if just one record or a small column is UPDATEd</i>.  When searching for the WHERE condition to find the UPDATE target, yes, the use of index will affect the searching time. But also you must remember that the <b>size of a record</b>&nbsp;also affects UNDO/REDO logging, <b>not</b> the size of UPDATE target column. <b>We can assume that the smaller the size of record to be UPDATEd and the longer the fixed-length compared to the existing size, the more advantageous it is for UPDATE performance</b>. 
</p><p>Under the assumption that UPDATE of a variable-length column occurs always, you can consider adjusting the system parameter <b>unfill_factor</b> (the default value 0.1) value, which controls the disk space of a pre-allocated page for data UPDATE.  For example, suppose the value of unfill_factor is 0.1, there will be about 10% of extra space in a page when data INSERT occurs continuously; thus, the remained 10% of extra space could be used for INSERT for the same page or for UPDATE.
</p><p>UPDATE requires&nbsp;<b>update lock</b> and <b>key lock</b>. You should understand that these could lead to standby or deadlock of competing transactions. If an unexpected delay or deadlock occurs, <b>you should check if an index configuration for UPDATE column is appropriate, or if the number of indexes on the column could be minimized</b>. 
</p><p>I hope that this article and the recommendations I gave&nbsp;to reduce the burden of UPDATE execution&nbsp;provide you an opportunity to understand the locking and storage structure usage methods in CUBRID database when executing UPDATE operations.</p><p>By Lee Donghyun, CUBRID Manual and Release Notes writer, CUBRID DBMS Development Lab, NHN Corporation.</p>]]></description>
                        <pubDate>Wed, 18 Apr 2012 14:01:57 +0900</pubDate>
                        <category>SQL</category>
                        <category>UPDATE</category>
                        <category>RDBMS</category>
                        <category>Memory Management</category>
                        <category>Optimizations</category>
                        <category>table lock</category>
                        <category>key lock</category>
                        <category>update lock</category>
                        <category>storage</category>
                        <category>index</category>
                        <category>architecture</category>
                        <category>OID</category>
                        <category>OOID</category>
                        <category>OFID</category>
                                </item>
        										        <item>
            <title>jOOQ: Java Object Oriented Querying now supports CUBRID Database</title>
            <dc:creator>Esen Sagynov</dc:creator>
            <link>http://www.cubrid.org/blog/cubrid-appstools/jooq-java-object-oriented-querying-now-supports-cubrid-database/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/cubrid-appstools/jooq-java-object-oriented-querying-now-supports-cubrid-database/</guid>
                        <comments>http://www.cubrid.org/blog/cubrid-appstools/jooq-java-object-oriented-querying-now-supports-cubrid-database/#comment</comments>
                                    <description><![CDATA[<p>It was great couple of weeks for CUBRID project! We opened this month with participating at&nbsp;the&nbsp;<a href="/blog/cubrid-life/meet-cubrid-developers-at-russian-internet-technologies-2012-conference/" target="_self">Russian Internet Technologies 2012 Conference</a>&nbsp;where our team presented CUBRID very successfully. Some 40+ attendees bombarded us with really interesting questions. It was just amazing! In addition, we have&nbsp;recently&nbsp;launched <a href="/affiliates" target="_self">CUBRID Affiliates</a> program where we invite all members of open source community to become the CUBRID Partners by adding support for CUBRID RDBMS in their open source applications.</p>

<p><img style="float:left;margin-right:10px" src="http://www.cubrid.org/files/attach/images/220547/193/326/jooq-logo.jpg" alt="jooq-logo.jpg" width="250" height="180" editor_component="image_link" />So far it has been very successful that I am very excited to announce our first partner <a href="/wiki_apps/entry/jooq-java-object-oriented-querying" target="_self">jOOQ</a> (Java Object Oriented Querying), an open source SQL query builder with Active Record modeling which provides easy 1:1 mapping between tables/views in your database and classes in your Java application.</p><p>According to <a href="https://github.com/lukaseder" target="_self">Lukas Eder</a>, the core developer,&nbsp;jOOQ is a type safe SQL query builder which allows to model standard and&nbsp;vendor-specific SQL constructs directly in a Java fluent API. "Using&nbsp;its code generator, its intuitive API and your favourite IDE for&nbsp;syntax-autocompletion, you can greatly increase your productivity&nbsp;writing and executing SQL in your Java application. Use jOOQ for your&nbsp;migration from MySQL to CUBRID and let SQL be fun again!" says Lukas.</p><p>We have already tested jOOQ with CUBRID and created a <a href="/wiki_apps/entry/jooq-cubrid-tutorial" target="_self">tutorial</a> for you to quickly get started.&nbsp;Here are the major set of features which make jOOQ very useful for database based Java application developers:</p>

<ul style="list-style-image: url(http://www.jooq.org/img/favicon-16.png)"><li>Code Generation: jOOQ generates a simple Java representation of your database schema. Every table, view, stored procedure, enum, UDT is a class.</li><li>Active records: jOOQ implements an easy-to-use active record pattern. It is NOT an OR-mapper, but provides a 1:1 mapping between tables/views and classes. Between columns and members.</li><li>Typesafe SQL: jOOQ allows for writing compile-time typesafe querying using its built-in fluent API.</li><li>SQL standard: jOOQ supports all standard SQL language features including the more complex UNION's, nested SELECTs, joins, aliasing</li><li>Vendor-specific feature support: jOOQ encourages the use of vendor-specific extensions such as stored procedures, UDT's and ARRAY's, recursive queries, and many more.</li></ul>

<p></p><p>When we have asked Lukas about what it was like to add CUBRID Database support to an open source application used by thousands of users, he replied:&nbsp;"At first sight, I was thrilled by the amount of functionality,&nbsp;documentation, and tooling offered by this new emerging open source&nbsp;database. Its integration into jOOQ was straight-forward thanks to the&nbsp;detailed documentation and compatibility with MySQL."</p><p>On behalf of CUBRID, I would like to thank Lukas for his valuable contribution to CUBRID open source community. I am sure CUBRID users will greatly benefit from jOOQ's rich functionality.</p><p><b>Stay tuned!</b> We will be announcing more of such interesting open source projects in the coming week.</p><blockquote class="q4"><p style="text-align: center;"><span style="color: rgb(255, 0, 0); ">Information for our readers!</span></p><p style="text-align: center;">If you develop an open source application and would like to become a <b>CUBRID Partner</b> by supporting CUBRID Database in your project, contact us by email <a href="mailto:affiliates@cubrid.org" target="_self">affiliates@cubrid.org</a>. In your letter please provide an overview of your software, project links, and your statement on behalf of your project. We will be very glad to have you onboard!</p></blockquote><p></p><p>


</p>]]></description>
                        <pubDate>Fri, 13 Apr 2012 12:15:55 +0900</pubDate>
                        <category>jOOQ</category>
                        <category>Java</category>
                        <category>programming</category>
                        <category>ActiveRecord</category>
                        <category>CUBRID Affiliates</category>
                                </item>
        										        <item>
            <title>NoSQL Benchmarking</title>
            <dc:creator>Hye Jeong Lee</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/nosql-benchmarking/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/nosql-benchmarking/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/nosql-benchmarking/#comment</comments>
                                    <description><![CDATA[<p>NoSQL is the talk of the town. And we have already covered <a title="What is NoSQL for?" href="http://blog.cubrid.org/web-2-0/what-is-nosql-for/">what it is for</a> in one of our previous blogs. Today I would like to share the NoSQL benchmark test results we have recently conducted. It will help you to understand if the soon to develop system is compatible to NoSQL, and which NoSQL product to select.</p>

<p>In this article we will reveal the characteristics of <a title="Cassandra - CUBRID Blog" href="http://blog.cubrid.org/tags/cassandra/">Cassandra</a>, <a title="HBase - CUBRID Blog" href="http://blog.cubrid.org/tags/hbase">HBase</a> and <a title="MongoDB - CUBRID Blog" href="http://blog.cubrid.org/tags/mongodb/">MongoDB</a> identified through multiple workloads.</p>

<h2>Why NoSQL?</h2>

<p>The interest in NoSQL continues to rise because the amount of data to process continues to increase. International internet companies, including <a title="Google - CUBRID Blog" href="http://blog.cubrid.org/tags/google/">Google</a> and <a title="Facebook - CUBRID Blog" href="http://blog.cubrid.org/tags/facebook/">Facebook</a>, have their own NoSQL solution designed to process the exploding amount of data.</p>

<blockquote>Why are they using NoSQL instead of RDBMS?</blockquote>

<p><a title="Twitter - CUBRID Blog" href="http://blog.cubrid.org/tags/twitter/">Twitter</a> is still <a title="Decomposing Twitter (Database Perspective)" href="http://blog.cubrid.org/web-2-0/decomposing-twitter-database-perspective/">using</a> MySQL. Although smaller than Facebook, the international SNS company MySpace uses MS SQL Server as their main storage.</p>

<p>RDBMS is known to experience burden when processing tera or peta unit large sized data. However, this can be resolved through sharding. For instance, <a title="NHN - CUBRID Blog" href="http://blog.cubrid.org/tags/nhn/">NHN</a>’s Café, Blog and News services use RDBMS through sharding.</p>

<p>There is no single correct answer in processing bulk data. Since every situation is different, the company must select the solution that best fits their situation and apply that for seamless service.</p>

<blockquote>Out of the RDBMSs, Oracle is an exception since Oracle’s performance and functions, such as mass data processing or data synchronization, are far more superior to other RDBMS. However, the high cost can be a problem. Depending on the size, it may be more economical to develop a NoSQL than purchasing an Oracle license.</blockquote>

<p>Even if you have enough expertise on how to process bulk data with RDBMS, we will need to have continuous interest and training in NoSQL. NoSQL is gaining popularity because of its ability to process mass data, but it still has many technical (or functional) limitations compared to RDBMS. However, this will be resolved as time passes.</p>

<a name="more"></a>
<p>NoSQL provides a <b>non-relational</b>, and in the long run, <b>schema-free data model</b>, allowing the horizontal extension of the system. Instead, it is <b>less structured</b> than RDBMS and <b>does not guarantee ACID</b>. Therefore, after the INSERT operation is completed and SELECT conducted, a different value can be acquired. And after the NoSQL demo has failed and restored, the stored value may be different than before. Operations such as <b>transactions or join cannot be conducted</b>.</p>

<p>While ACID has been abandoned, the flexibility, scalability and usability of data storage have increased. Therefore, it is more suitable for explosive amounts of data processing.</p>

<p>Now let’s see if the NoSQL products really play the expected part for the internet services you are to develop. Why don’t we take a look at the characteristics of the most widely used NoSQL products (Cassandra, HBase, MongoDB) by looking into each of its architectures and benchmark tests that were conducted.</p>

<h2>Benchmarking Tests using YCSB</h2>

<p><a title="Yahoo Cloud Servicing Benchmark" href="http://research.yahoo.com/Web_Information_Management/YCSB">YCSB</a> (Yahoo Cloud Servicing Benchmark) is a test framework developed by Yahoo. It allows to conduct benchmark tests on storages by creating "<em>work loads</em>". Through this benchmark, the storage most suitable for the service that is to be developed can be selected.</p>

<p>Basic operations are Insert, Update, Read, and Scan. There are basic workload sets that combine the basic operations, but new additional workloads can also be created.</p>

<p>YCBS currently supports Cassandra, HBase, MongoDB, Voldemort and JDBC. If tests on other storages are needed, then use YCBS interfaces to test during the development process.</p>

<p>This article contains tests conducted on the following products and versions.</p>

<ul>
  <li><b>Cassandra-0.7.4<br /></b><em>Although Cassandra’s latest version is 0.8.0, we have decided to use the previous version known to be stable. Because when testing with the 0.8 version, the gossip protocol between nodes malfunctioned and the node up/down information was incorrect.</em></li>
  <li><b>HBase-0.90.2</b> (Hadoop-0.20-append)<br /><em>The HBase-0.90.2 (Hadoop-0.20-append) was selected because, if not the Hadoop-append version, there may be problems on decreased durability in HDFS.</em></li>
  <li><b>MongoDB-1.8.1</b></li>
</ul>

<p>The test workload is as follows.</p>

<ul>
  <li><b>Insert Only<br /></b>Enter 50 million 1K-sized records to the empty DB.</li>
  <li><b>Read Only<br /></b>Search the key in the <a title="Zipf Distribution" href="http://mathworld.wolfram.com/ZipfDistribution.html">Zipfian Distribution</a> for a one hour period on the DB that contains 50 million 1K-sized records.</li>
  <li><b>Read &amp; Update<br /></b>Conduct <em>read</em> and <em>update</em> one-on-one instead of <em>read</em> under the identical conditions of <em>Read Only</em>.</li>
</ul>

<p>There are three testing equipments with the same specifications:</p>

<ul>
  <li>Nehalem 6 Core x 2 CPU, 16GB Memory.</li>
</ul>

<p>Each conduct replicates and distributes three copies. However, with MongoDB the performance result was abnormally high when both replications and distribution compositions were organized, so the test was conducted only with the replica set. The parameter for each product is shown in the following listings. Other items were set to default.</p>

<ul><li>Cassandra</li></ul>

<div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url(modules/editor/components/code_highlighter/code.png) no-repeat top right;">
# If a minimum of one succeeds while replicating, then it is returned to application.
Consistency Level, Read=ONE, Write=ONE

# Can be set to periodic(default) or batch.
# Periodically writes (fsync) the commit log on the disk,
# and batch executes regularly (1ms) collecting those to fsync every time.
commitlog_sync: batch, commitlog_sync_batch_window_in_ms: 1

# Degree the key location is cached. When 1.0 - everything is cached.
key_cached=1.0
</div>

<ul><li>HBase</li></ul>

<div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url(modules/editor/components/code_highlighter/code.png) no-repeat top right;">
HeapSize, HBase=8G, HDFS=2G
</div>

<ul><li>MongoDB</li></ul>

<div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url(modules/editor/components/code_highlighter/code.png) no-repeat top right;">
# Size of Oplog. Oplog is the log the master accumulated for replication.
--oplogSize=100G
</div>

<p>The results are as shown in the following figure.</p>

<p><a href="http://blog.cubrid.org/wp-content/uploads/2011/09/db-test-results.png"><img title="Comparison of throughput per product" src="http://blog.cubrid.org/wp-content/uploads/2011/09/db-test-results.png" alt="Comparison of throughput per product" width="587" height="418" editor_component="image_link"/></a></p>

<ol>
  <li>All three products showed better throughput in INSERT.</li>
  <li>Cassandra showed outstanding throughput in INSERT-only with 20,000 ops.</li>
  <li>HBase also presented relatively good performance in INSERT-only.</li>
  <li>The products did not show large differences with READ-only than INSERT-only.</li>
  <li>HBase’s performance was better than Cassandra in READ-only.</li>
  <li>Cassandra’s performance in READ-and-UPDATE was better than the other two products. Cassandra’s READ-and-UPDATE might have been higher than READ-only due to Cassandra’s excellent insert throughout.</li>
  <li>MongoDB’s throughout in all three conditions was the lowest of the three products. MongoDB, which uses the Memory Mapped File (mmap), probably showed poor performance because the large data size exceeded the physical memory size.</li>
</ol>
Let’s take a look at why each product showed such difference in performance.

<h2>Cassandra and HBase Architecture</h2>

<p>Both Cassandra and HBase are influenced by Google’s BigTable. (<em>Although Cassandra was directly influenced by Amazon’s Dynamo.</em>) <b>BigTable</b> is a Column-Oriented DB that stores data in a Multidimensional Sorted Map format and has the <b>&lt;row key, column family, column key&gt;</b> data structure. <b><em>Column family</em></b> is a basic unit that stores data with column groups that are related to each other.</p>

<p>In BigTable, data is written basically with the append method. In other words, when modifying data, the updates are appended to a file, rather than an in-place update in the stored file. The figure below shows BigTable’s data read/insert path.</p>

<p><a href="http://blog.cubrid.org/wp-content/uploads/2011/09/bigtable-internal-structure.png"><img title="BigTable’s Internal Structure" src="http://blog.cubrid.org/wp-content/uploads/2011/09/bigtable-internal-structure.png" alt="BigTable’s Internal Structure" width="417" height="250" editor_component="image_link"/></a></p>

<p>When a write operation is inserted, it is first placed in a memory space called <em><b>memtable</b></em>. If the <em>memtable</em> is full, then the whole data is stored in a file called <em><b>SSTable</b> (Sorted String Table)</em>. Data may be lost if the server collapses before the <em>memtable</em> data is moved to <em>SSTable</em>, so to provide durability it is necessary to save the history of commit logs every time before writing to the <em>memtable</em>. When conducting the read operation, first find the pertaining key in the <em>memtable</em>. If it is not in the <em>memtable</em>, search for it in the <em>SSTable</em>. You may have to search multiple <em>SSTables</em>.</p>

<p>There are advantages in the writing operation if this architecture is used. This is because the ‘writing’ operation is only recorded in the memory and moved to the actual disk only after a certain amount has been accumulated. <b>Therefore, concurrent I/O can be avoided.</b> However, when "<em>reading</em>", if "<em>reading</em>" is done in the <em>SSTable</em> and not in the <em>memtable</em>, then the performance will relatively decrease. Both Cassandra and HBase use bloom filter to quickly judge whether the key exists in the SSTable and creates an index for use. However, if there are many <em>SSTable</em>s, then a lot of I/O will be created during the reading operation. Therefore, compaction is done to improve the reading performance. <b>Compaction</b> is where two <em>SSTable</em>s merge and sort to become one <em>SSTable</em>, which decreases the number of <em>SSTable</em>s. The reading and writing performance improved as more compactions are done.</p>

<p><em>For these reasons READ and READ-and-UPDATE are much slower than INSERT operations in these NoSQL solutions.</em></p>

<h2>Cassandra</h2>

<p>Additionally, <b>Cassandra uses consistent hashing</b>. The HBase and Casandra may have their similarities, there are differences as well. Cassandra prefers <b>AP</b> (Availability &amp; Partition tolerance) while HBase prefers <b>CP</b> (Consistency &amp; Partition tolerance). <b>CAP theorem</b> is a theory in Distributed Computing.</p>

<blockquote>The theory claims that there is no system that provides all three Consistency, Availability and Partition tolerance. For example, replications must be made in multiple nodes to increase usability, and the adjustability between replicated data must be met. However, in order to make operation possible, even during network partitioning, it becomes difficult to guarantee the adjustability between replications or data. Therefore, only a part of the CAP can be provided.</blockquote>

<p>As mentioned before, Amazon’s Dynamo has a direct influence on Cassandra. Dynamo uses consistent hashing to <em>disperse data to the key-value store, and provides high adjustability</em>. Consistent hashing sequences the value (slot) that hashed the key and placed it in a ring format. The multiple nodes that create the cluster processes certain ranges of the ring. Therefore, every time a node in the cluster falls out or comes in, the closed node on the ring can take over the concerned range or distribute the range without rehashing.</p>

<p>Cassandra also raises the usability level with the concept of consistency level. This concept is related to replication. Confirmation of the number of replications and the completion of replication can be adjusted with the system parameter. For example, if three replications are maintained and a write operation is inserted, then the operation is only considered to be successful if the three replications are completed.</p>

<p>However, Cassandra allows only N (under 3) number of executions to be checked and immediately returns to value. Therefore, write can be conducted successfully even with failures in the replication node, which raises usability. Histories of failed write operations are recorded on a different node, and the operation can be retried at a later date (this is called “<b>hinted handoff</b>”). Since the success of replicated writing is not guaranteed, the data suitability is checked in the reading stage. Generally, if there are multiple replications, it is collected into one when reading. However, Cassandra keeps in mind that not all replications match, and reads the data from all three replications, checks whether it is identical, and restores the latest data if it is not suitable (this is called “<b>read repair</b>”).</p>

<p><em>This is why Cassandra is slower in reading than writing.</em></p>

<h2>HBase</h2>

<p>Now let’s look into HBase. HBase has the same structure as BigTable. While BigTable operates on the <em><b>tablet</b></em> unit, HBase disperses and replicates with the <em><b>region</b></em> unit. Key is arranged according to ranges, and the location of the region, where the key is stored in, is saved as meta data (this is called <em><b>meta region</b></em>). Therefore, if a key is inserted, first find the region, and later the client will cache this information. HBase places the writing operation in a single region, without distributing and splits the region if it becomes too large. Adjustments, such as creating regions in advance, must be made for the action above.</p>

<p>HDFS is in charge of data storage and replication. When writing a file with Hadoop’s distribution file system, HDFS writes multiple replications (synchronous replication) and only reads one of them when reading. This guarantees data integrity and lowers reading overhead. However, since HBase and HDFS operates separately, the location of the node that contains <em>memtable</em> and <em>SSTable</em> may change, which may cause additional network I/O.</p>

<p>What happens if there is a failure in the node? If the region server collapses, other nodes take over the tasks which comprised the region. In other words, the commit log that pertains to the region is replayed and <em>memtable</em> is created. If the failed node contains HDFS’s data, then chunk that pertains to the node is migrated to a different node.</p>

<p>Thus, we have looked at the similarities and differences of Cassandra and HBase.</p>

<blockquote>Then why did the two products show a difference in writing during the comparison test?</blockquote>

<ol>
  <li>First of all, there is a <b>difference in commit log</b>. Cassandra writes the commit log once in the local file system. However, HBase enter the commit log in the HDFS and HDFS conducts the replication. Data locality is not put into consideration, so the file write request will probably be sent to a different physical node in the network.</li>
  <li>Second, Cassandra receives the write request on all three nodes, but HBase only ‘writes’ on a single region in the beginning, and receives requests on only one node.</li>
</ol>
<blockquote>Then why is there a difference in reading performance?</blockquote>

<p>There are various differences, but for one READ request Cassandra reads the data three times while HBase only reads the data once. This places an influence on the throughput.</p>

<h2>MongoDB Architecture</h2>

<p>MongoDB is unlike Cassandra or HBase eplained earlier. There are too many functional groups that can be classified as NoSQL, which makes it difficult to compare with Cassandra and HBase on the same level.</p>

<p><em>Cassandra and HBase is for processing full-scale large amounts of data, while MongoDB can be used quickly, schema-free when using a certain amount of data.</em></p>

<p>MongoDB adopts a <b>documented-oriented format</b>, so it is more similar to RDBMS than a key-value or column oriented format.</p>

<p>MongoDB <b>operates on a memory base and places high performance above data scalability</b>. If reading and writing is conducted within the usable memory, then high-performance is possible. However, performance is not guaranteed if operations exceed the given memory. Therefore, <b>MongoDB should be used as a medium or small-sized storage system</b>.</p>

<p>Configure a test condition similar to the original test on a lower specification server and test 300 thousand records instead of 50 million, and MongoDB will record greater performance than Cassandra or HBase.</p>

<p><b>Mongo DB uses <a title="BSON" href="http://bsonspec.org/">BSON</a> for data storage</b>. (As known as Binary JSON, but is similar to Hessian than JSON in data encoding format and expressive datatype.)</p>

<p>The logical unit that is expressed using BSON is called <em><b>document</b></em>. (When using NPC as an example, it is the same as when the NPC data is recorded on the disk and searched.) <em>Document</em> is a concept that corresponds to a <b>row</b> in RDBMS. The difference is that a <em>document</em> in MongoDB does not have a schema.</p>

<p>Accumulated documents<em> </em>are called <em><b>collections</b></em>. A collection corresponds to a <em><b>table</b></em> in RDBMS.</p>

<p>Basic query method is to search the collection to find documents that meet the conditions. Each document has a field called <b>_id</b>, which acts as the OID (Object Identifier), and all query results are returned with this <em>_id</em>.</p>

<p>Index can also be created for collections. An index can be prepared for the fields in the document. This index is implemented in <b>B-Tree</b>, similar to that of RDBM’s index. Each collection creates an index for <em>_id</em> by default. One of the strengths of MongoDB is that its functions are similar to RDBMS, in that it supports indexing and JOIN.</p>

<p>Further, we will now look at the structure of MongoDB.</p>

<h3>MongoDB Structure</h3>

<p>MongoDB is configurable in replication and distribution configuration. The system configuration recommended by MongoDB is three shard servers and three replica sets for each server (in other words, nine nodes). <b>Replications</b> are made possible by Master/Slave or a replica set. Replica set supports automatic failover. It has one master and multiple slaves, and write can only be sent to the master. If the master is terminated, service is resumed after one of the slaves are appointed as a master.</p>

<p>The distribution method provided by MongoDB is <b>sharding</b>. Each collection can shard, and a field in the Collection can designate a shard key. Like HBase, sharding is operated with the <b>Order-preserving partitioning method</b>. Chunk is included in the <b>&lt;collection, minkey, maxkey&gt;</b>, a continuous data range within shard, and can be as big as 64M. Chunks that have exceeded the maximum size can split into two chunks, and the divided chunks can migrate to different shard servers. The following figure contains a picture of MongoDB, which is composed of shards and replica sets.</p>

<p><a href="http://blog.cubrid.org/wp-content/uploads/2011/09/mongodb-composition.png"><img title="MongoDB structure" src="http://blog.cubrid.org/wp-content/uploads/2011/09/mongodb-composition.png" alt="MongoDB structure" width="570" height="376" editor_component="image_link"/></a></p>

<p>The client first contacts a process called <b>mongos</b>, which is in charge of <em>routing</em> and <em>coordination</em>. Coordination is done over multiple nodes through requests and the results are collected and returned. The config server retains meta information on shards and chunks.</p>

<p>Now let’s look into MongoDB's internal structure. MongoDB uses the <b>asynchronous method for replication</b>. When a “write” operation is inserted, master stores the history in <em>Oplog</em>. <b>Oplog</b> is a fixed sized, FlfO method collection called capped collection. Logs accumulated in the Oplog are regularly polled by the slave, read, then implemented. If the slave failed to replay the log while the Oplog fills up, then the slave must suspend log-based replications and synchronizes by resyncing the master’s data. One of Oplog’s other distinctive characteristics is that it can conduct the saved operations idempotently when replaying the log. Operation logs are saved in the order it was executed in, so logs can be replayed after that period. Ops such as <em>increment</em> are changed to set ops when logged for this purpose.</p>

<p>MongoDB’s replication and failover method and query power is similar to RDBMS. The most significant difference is that flexibility in data storage is provided to the application while schema-free data is stored.</p>

<h2>RDBMS Architecture</h2>

<p>Unlike NoSQL, RDBMS is <b>"read" operation oriented</b>. The detailed method differs for each product, but generally NoSQL products are implemented so that mass data can be ‘<b>written</b>’ quickly. On the other hand, RDBMS, which is ‘read’ oriented, not only enables quick reading, but also provides many functions and inquiry features. DBMS can quickly inquire values using indexes, but at the same time indexes slow down ‘writing’. Since an index must be configured for every ‘writing’ operation, the more indexes there are, the more time is needed to configure the indexes.</p>

<p>The difference of RDBMS and NoSQL can be compared with ACID and BASE, but comparisons can also be made with reading and writing.</p>

<p>If the business you are to build requires more reading than writing, and needs complex reading methods, as well as basic aggregate functions such as SUM() or AVG(), then RDBMS might be a better choice than NoSQL.</p>

<h2>Summary</h2>

<p>We have looked at benchmark tests done on Cassandra, HBase, MongoDB and the differences between the products. Cassandra and HBase show excellent writing abilities, but its reading performance did not meet expectations. This was because unlike existing RDBMSs, the two products were optimized for writing, and this resulted in a lot of concurrent I/O when reading.</p>

<p>MongoDB has similar structures to that of RDBMS and shows great flexibility in data modeling especially for medium and small-sized businesses.</p>

<p>By Lee Hye Jeong, Storage System Development Team, NHN Corporation.</p>]]></description>
                        <pubDate>Thu, 08 Sep 2011 02:27:43 +0900</pubDate>
                        <category>benchmark</category>
                        <category>MS SQL</category>
                        <category>NHN</category>
                        <category>Cassandra</category>
                        <category>Twitter</category>
                        <category>NoSQL</category>
                        <category>Facebook</category>
                        <category>Google</category>
                        <category>BigTable</category>
                        <category>Dynamo</category>
                        <category>Amazon</category>
                        <category>MongoDB</category>
                        <category>Oracle</category>
                        <category>Dev Platform Blog</category>
                        <category>HBase</category>
                                    <slash:comments>12</slash:comments>
                    </item>
        										        <item>
            <title>Understanding Java Garbage Collection</title>
            <dc:creator>Sangmin Lee</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/#comment</comments>
                                    <description><![CDATA[<p>What are the benefits of knowing how garbage collection (GC) works in <a href="/blog/tags/Java/" target="_self">Java</a>?&nbsp;Satisfying the intellectual curiosity as a software engineer would be a valid cause,&nbsp;but also, understanding how GC works can help you write much better Java applications.</p><p>This is a very personal and subjective opinion of mine, but I believe that a person well versed in GC tends to be a better Java developer. If you are interested in the GC process, that means you have experience in developing applications of certain size. If you have thought carefully about choosing the right GC algorithm, that means you completely understand the features of the application you have developed. Of course, this may not be common standards for a good developer. However, few would object when I say that understanding GC is a requirement for being a great Java developer.&nbsp;</p><p>This is the first of a series of "<i><a href="/blog/tags/Garbage%20Collection/" target="_self">Become a&nbsp;Java GC Expert</a></i>" articles. I will cover the <i>GC introduction</i> this time, and in the next article, I will talk about analyzing GC status and GC tuning examples from <a href="/blog/tags/NHN/" target="_self">NHN</a>.</p><p>The purpose of this article is to introduce GC to you in an easy way. I hope this article proves to be very helpful. Actually, my colleagues have already published <a href="/blog/tags/Java/" target="_self">a few great articles on Java Internals</a>&nbsp;which became quite popular on Twitter. You may refer to them as well.</p><p>Returning back to Garbage Collection, there is a term that you should know before learning about GC. The term is "<b id="stop-the-world">stop-the-world</b>." Stop-the-world will occur no matter which GC algorithm you choose. <i>Stop-the-world</i> means that the <a href="/blog/dev-platform/understanding-jvm-internals/" target="_self">JVM</a> is stopping the application from running to execute a GC. When stop-the-world occurs, every thread except for the threads needed for the GC will stop their tasks. The interrupted tasks will resume only after the GC task has completed. GC tuning often means reducing this stop-the-world time.</p><h2>Generational Garbage Collection&nbsp;</h2><p>Java does not explicitly specify a memory and remove it in the program code. Some people sets the relevant object to null or use System.gc() method to remove the memory explicitly. Setting it to null is not a big deal, but calling System.gc() method will affect the system performance drastically, and must not be carried out. (Thankfully, I have not yet seen any developer&nbsp;in NHN&nbsp;calling this method.)</p><p>In Java, as the developer does not explicitly remove the memory in the program code, the garbage collector finds the unnecessary (garbage) objects and removes them. This garbage collector was created based on the following two hypotheses. (It is more correct to call them suppositions or preconditions, rather than hypotheses.)&nbsp;</p><p></p><ul><li>Most objects soon become unreachable.</li><li>References from old objects to young objects only exist in small numbers.</li></ul><p></p><p>These hypotheses are called the <b>weak generational hypothesis</b>. So in order to preserve the strengths of this hypothesis, it is physically divided into two - <b>young generation</b> and <b>old generation</b> - in HotSpot VM.</p><p><b>Young generation</b>: Most of the newly created objects are located here. Since most objects soon become unreachable, many objects are created in the young generation, then disappear. When objects disappear from this area, we say a "<b>minor GC</b>" has occurred.&nbsp;</p><p><b>Old generation</b>: The objects that did not become unreachable and survived from the young generation are copied here. It is generally larger than the young generation. As it is bigger in size, the GC occurs less frequently than in the young generation. When objects disappear from the old generation, we say a "<b>major GC</b>" (or a "<b>full GC</b>") has occurred.&nbsp;</p><p>Let's look at this in a chart.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/java-gc-area-data-flow.png" alt="Figure 1: GC Area &amp; Data Flow." width="352" height="307" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 1: GC Area &amp; Data Flow.</b></p><p>The <b>permanent generation</b> from the chart above is also called the "<b>method area,</b>" and it stores classes or interned character strings. So, this area is definitely not for objects that survived from the old generation to stay permanently. A GC may occur in this area. The GC that took place here is still counted as a major GC.&nbsp;</p><p>Some people may wonder:</p><blockquote class="q2"><p><b>What if an object in the old generation need to reference an object in the young generation?</b></p></blockquote><p>To handle these cases, there is something called the a "<b>card table</b>" in the old generation, which is a <i>512 byte chunk</i>. Whenever an object in the old generation references an object in the young generation, it is recorded in this table. When a GC is executed for the young generation, only this card table is searched to determine whether or not it is subject for GC, instead of checking the reference of all the objects in the old generation. This card table is managed with <b>write barrier</b>. This <i>write barrier</i> is a device that allows a faster performance for minor GC. Though a bit of overhead occurs because of this, the overall GC time is reduced.&nbsp;</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/card-table-structure.png" alt="Figure 2: Card Table Structure." width="374" height="225" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 2: Card Table Structure.</b></p><h2>Composition of the Young Generation</h2><p>In order to understand GC, let's learn about the young generation, where the objects are created for the first time. The young generation is divided into 3 spaces.&nbsp;</p><p></p><ul><li>One&nbsp;<b>Eden</b> space</li><li>Two&nbsp;<b>Survivor</b> spaces</li></ul><p></p><p>There are 3 spaces in total, two of which are Survivor spaces. The order of execution process of each space is as below:</p><p></p><ol><li>The majority of newly created objects are located in the Eden space.</li><li>After one GC in the Eden space, the surviving objects are moved to one of the Survivor spaces.&nbsp;</li><li>After a GC in the Eden space, the objects are piled up into the Survivor space, where other surviving objects already exist.</li><li>Once a Survivor space is full, surviving objects are moved to the other Survivor space. Then, the Survivor space that is full will be changed to a state where there is no data at all.</li><li>The objects that survived these steps that have been repeated a number of times are moved to the old generation.</li></ol><p></p><p>As you can see by checking these steps, one of the Survivor spaces must remain empty. If <i>data exists in both Survivor spaces, or the usage is 0 for both spaces</i>, then take that as a sign that <b>something is wrong with your system</b>.</p><p>The process of data piling up into the old generation through minor GCs can be shown as in the below chart:</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/before-and-after-java-gc.png" alt="Figure 3: Before &amp; After a GC." width="382" height="715" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 3: Before &amp; After a GC.</b></p><p>Note that in HotSpot VM, two techniques are used for faster memory allocations. One is called "<b>bump-the-pointer</b>," and the other is called "<b>TLABs (Thread-Local Allocation Buffers)</b>."&nbsp;</p><p><b>Bump-the-pointer</b> technique tracks the last object allocated to the Eden space. That object will be located on top of the Eden space. And if there is an object created afterwards, it checks only if the size of the object is suitable for the Eden space. If the said object seems right, it will be placed in the Eden space, and the new object goes on top. So, when new objects are created, only the lastly added object needs to be checked, which allows much faster memory allocations. However, it is a different story if we consider a multithreaded environment. To save objects used by multiple threads in the Eden space for Thread-Safe, an inevitable lock will occur and the performance will drop due to the lock-contention.&nbsp;<b>TLABs</b> is the solution to this problem in HotSpot VM. This allows each thread to have a small portion of its Eden space that corresponds to its own share. As each thread can only access to their own TLAB, even the bump-the-pointer technique will allow memory allocations without a lock.&nbsp;</p><p>This has been a quick overview of the GC in the young generation. You do not necessarily have to remember the two techniques that I have just mentioned. You will not go to jail for not knowing them. But please remember that after the objects are first created in the Eden space, and the long-surviving objects are moved to the old generation through the Survivor space.</p><h2>GC for the Old Generation</h2><p>The old generation basically performs a GC when the data is full. The execution procedure varies by the GC type, so it would be easier to understand if you know different types of GC.&nbsp;</p><p>According to JDK 7, there are 5 GC types.&nbsp;</p><p></p><ol><li>Serial GC</li><li>Parallel GC</li><li>Parallel Old GC (Parallel Compacting GC)</li><li>Concurrent Mark &amp; Sweep GC &nbsp;(or "CMS")</li><li>Garbage First (G1) GC</li></ol><p></p><p>Among these, the <b>serial GC must not be used on an operating server</b>. This GC type was created when there was only one CPU core on desktop computers. Using this serial GC will drop the application performance significantly.&nbsp;</p><p>Now let's learn about each GC type.</p><h3>Serial GC (-XX:+UseSerialGC)</h3><p>The GC in the young generation uses the type we explained in the previous paragraph. The GC in the old generation uses an algorithm called "<b>mark-sweep-compact</b>."</p><p></p><ol><li>The first step of this algorithm is to mark the surviving objects in the old generation.</li><li>Then, it checks the heap from the front and leaves only the surviving ones behind (sweep).</li><li>In the last step, it fills up the heap from the front with the objects so that the objects are piled up consecutively, and divides the heap into two parts: one with objects and one without objects (compact).</li></ol><p></p><p>The serial GC is suitable for a small memory and a small number of CPU cores.</p><h3>Parallel GC (-XX:+UseParallelGC)</h3><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/difference-between-the-serial-gc-and-parallel-gc.png" alt="Figure 4: Difference between the Serial GC and Parallel GC." width="645" height="211" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 4: Difference between the Serial GC and Parallel GC.</b></p><p>From the picture, you can easily see the difference between the serial GC and parallel GC. While the serial GC uses only one thread to process a GC, the parallel GC uses several threads to process a GC, and therefore, faster. This GC is useful when there is enough memory and a large number of cores. It is also called the "<b>throughput GC</b>."&nbsp;</p><h3>Parallel Old GC(-XX:+UseParallelOldGC)</h3><p>Parallel Old GC was supported since JDK 5 update. Compared to the parallel GC, the only difference is the GC algorithm for the old generation. It goes through three steps: <i>mark – summary – compaction</i>. The summary step identifies the surviving objects separately for the areas that the GC have previously performed, and thus different from the sweep step of the mark-sweep-compact algorithm. It goes through a little more complicated steps.</p><h3 id="cms-gc">CMS GC (-XX:+UseConcMarkSweepGC)</h3><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/serial-gc-and-cms-gc.png" alt="Figure 5: Serial GC &amp; CMS GC." width="683" height="420" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 5: Serial GC &amp; CMS GC.</b></p><p>As you can see from the picture, the Concurrent Mark-Sweep GC is much more complicated than any other GC types that I have explained so far. The early <i>initial mark</i> step is simple. The surviving objects among the objects the closest to the classloader are searched. So, the pausing time is very short. In the <i>concurrent mark</i> step, the objects referenced by the surviving objects that have just been confirmed are tracked and checked. The difference of this step is that it proceeds while other threads are processed at the same time. In the <i>remark</i> step, the objects that were newly added or stopped being referenced in the concurrent mark step are checked. Lastly, in the <i>concurrent sweep</i> step, the garbage collection procedure takes place. The garbage collection is carried out while other threads are still being processed. Since this GC type is performed in this manner, the pausing time for GC is very short. The CMS GC is also called the low latency GC, and is <b>used when the response time from all applications is crucial</b>.&nbsp;</p><p>While this GC type has the advantage of short stop-the-world time, it also has the following disadvantages.</p><p></p><ul><li>It uses more memory and CPU than other GC types.</li><li>The compaction step is not provided by default.</li></ul><p></p><p>You need to carefully review before using this type. Also, if the compaction task needs to be carried out because of the many memory fragments, the stop-the-world time can be longer than any other GC types. You need to check how often and how long the compaction task is carried out.</p><h3>G1 GC</h3><p>Finally, let's learn about the garbage first (G1) GC.&nbsp;</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/284/313/layout-of-g1-gc.png" alt="Figure 6:&amp;nbsp;Layout of G1 GC." width="153" height="169" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 6:&nbsp;Layout of G1 GC.</b></p><p>If you want to understand G1 GC, forget everything you know about the young generation and the old generation. As you can see in the picture, one object is allocated to each grid, and then a GC is executed. Then, once one area is full, the objects are allocated to another area, and then a GC is executed. The steps where the data moves from the three spaces of the young generation to the old generation cannot be found in this GC type. This type was created to replace the CMS GC, which has causes a lot of issues and complaints in the long term.</p><p>The biggest advantage of the G1 GC is its <b>performance</b>. It is faster than any other GC types that we have discussed so far. But in JDK 6, this is called an <i>early access</i> and can be used only for a test. It is officially included in JDK 7. In my personal opinion, we need to go through a long test period (at least 1 year) before NHN can use JDK7 in actual services, so you probably should wait a while. Also, I heard a few times that a JVM crash occurred after applying the G1 in JDK 6. Please wait until it is more stable.</p><p>I will talk about the <b>GC tuning</b> in the next issue, but I would like to ask you one thing in advance. If the size and the type of all objects created in the application are identical, all the GC options for WAS used in our company can be the same. But the size and the lifespan of the objects created by WAS vary depending on the service, and the type of equipment varies as well. In other words, just because a certain service uses the GC option "A," it does not mean that the same option will bring the best results for a different service. It is necessary to find the best values for the WAS threads, WAS instances for each equipment and each GC option by constant tuning and monitoring. This did not come from my personal experience, but from the discussion of the engineers making Oracle JVM for JavaOne 2010.</p><p>In this issue, we have only glanced at the GC for Java. Please look forward to our next issue, where I will talk about <b>how to monitor the Java GC status and tune GC</b>.&nbsp;</p><p>I would like to note that I referred to a new book released in December 2011 called "<i>Java Performance</i>" (<a href="http://amzn.com/0137142528" target="_self">Amazon</a>, it can also be viewed from safari online, if the company provides an account), as well as “<i>Memory Management in the Java HotSpotTM Virtual Machine</i>,” a white paper provided by the Oracle website. (The book is different from "<i>Java Performance Tuning</i>.")</p><p>By Sangmin Lee, Senior Engineer at Performance Engineering Lab, NHN Corporation.</p><p></p><p>


</p>]]></description>
                        <pubDate>Thu, 22 Mar 2012 17:39:58 +0900</pubDate>
                        <category>Java</category>
                        <category>Garbage Collection</category>
                        <category>performance</category>
                        <category>JVM</category>
                        <category>NHN</category>
                                    <slash:comments>6</slash:comments>
                    </item>
        										        <item>
            <title>Database Sharding Platform at NHN</title>
            <dc:creator>Jeon Won Hee</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/database-sharding-platform-at-nhn/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/database-sharding-platform-at-nhn/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/database-sharding-platform-at-nhn/#comment</comments>
                                    <description><![CDATA[<p>"<i>Ins and outs of NHN</i>" is a series of articles that compares platforms and services from third-party vendors with <a href="/blog/tags/NHN/" target="_self">NHN</a>'s own solutions.  The topic of this first article in the series is <b>Database&nbsp;Sharding Platform</b>. I will introduce about the efforts being made from inside and outside of NHN to implement&nbsp;Database Sharding. I will first explain the concept of Sharding data vs. Partitioning data. Then review the common methodology to implement sharding. And finally I will compares all sharding platforms. This article will be very interesting for developers interested in big data management.</p><h2>Database Expansion</h2><p>To store and search a volume of data which is so big that it cannot be handled by one database, you must find a way to use multiple databases.  Although there are some databases made for distributed environments, such as Cassandra or Dynamo, these have many functional constraints, such as weakness in terms of search range or inability to use the JOIN operations.  In order to expand data while using a relatively feature-rich functionality, it is recommended to use RDBMS by sharding the databases. 
</p><p>In the past, the Sharding logic was implemented directly on the application layer, but now there are an increasing number of examples introducing <i>Sharding platforms</i>&nbsp;which allow to move the Sharding logic from the application layer to database or middleware layers.  At a core level, Sharding platforms must respond effectively to ever-increasing data without failure, and handle different data characteristics and models depending on services.  
</p><p>In this article I will  compare <a href="http://spockproxy.sourceforge.net/">Spock Proxy</a>, the Sharding platform based on MySQL Proxy, <a href="https://github.com/twitter/gizzard">Gizzard</a>, created by Twitter, and <b>CUBRID SHARD</b>, native database sharding feature in CUBRID which is set to launch in the first half of 2012. A table of other solutions was previous posted at <a href="/blog/cubrid-life/database-sharding-with-cubrid/" target="_self">Database Sharding with CUBRID</a>.</p><h2>Horizontal Partitioning and Sharding</h2><p><b>Horizontal partitioning</b> is a design that divides and stores data, such as a schema, into two or more tables within <b><i>one database</i></b>. For example, to handle large data of user messages, such schema may be created so that messages by users from city A are stored in one table, while messages by users from city B are stored in another table. This allows to reduce the size of the index and increases the concurrency of operations. The key point in this approach is that the data is partitioned between tables&nbsp;<i><b>within a single database</b></i>.</p><p><b>Sharding</b>, on the other hand, is the <i><b>distributed</b></i>&nbsp;approach where data is horizontally partitioned between tables created in <i><b>physically different databases</b></i>. &nbsp;Thus, Sharding is a method to store the&nbsp;messages by users from city A&nbsp;in <i>database A</i> and&nbsp;messages by users from city B&nbsp;in <i>database B</i>. Here each database is called a&nbsp;<b>Shard</b>.</p><p>As you have to work on multiple databases, there could be limits to functionality according to circumstances and also a drawback in terms of consistency and replication, including JOIN operations.  In many cases, Sharding used to be implemented at the application server level.  There have been many attempts to provide this at the platform level.   These can be classified into a pattern that operates in an application server, such as  <a href="http://www.hibernate.org/subprojects/shards.html">Hibernate Shards</a>, a middle tier pattern as CUBRID SHARD, Spock Proxy, and Gizzard, and a pattern that provides the Sharding functionality from a database itself, e.g. <a href="http://devcafe.nhncorp.com/nStore">nStore</a> or <a href="http://www.mongodb.org/">MongoDB</a>.</p><h2>Middle Tier Sharding Platform</h2><p>By default, a Sharding platform should consider the following items: 
</p><ul><li>Database location abstraction</li><li>Scalability</li><li>Monitoring/Ease of operations</li></ul><p><b>Database location abstraction</b> and <b>scalability</b> are different from each other but connected.  <i>Database location abstraction</i> ensures that&nbsp;on the application layer&nbsp;you do not need to know which data (which Row) is located in which database. The application is connected only with the <i>Sharding platform</i>. Connecting to a database is what the Sharding platform should do. In addition, Sharding platform should carry out the task to add a replicated storage to a specific Shard (one of the partitioned databases) in order to migrate database for replacement <b><i>without restarting or changing the application code</i></b>. When the Sharding platform comes to a stop, it is obvious that an application server will not be able to access the database.  For this reason, the Sharding platform should provide&nbsp;<b><i>redundancy</i></b>.</p><p>For monitoring, the Sharding platform should be able to provide a number of requests and error information according to <b>Shard keys</b> (a standard to determine which data is stored in which database).</p><h2>Comparison between Spock Proxy and CUBRID SHARD</h2><p>The key function of the Sharding platform is the CRUD operation (CREATE, READ, UPDATE, DELETE) which chooses one database among many according to '<b><i>a standard set by developer</i></b>' in other words the <b>Sharding strategy</b>.   We will compare <b>Spock Proxy</b>, a typical Sharding platform of MySQL, with the <b>CUBRID SHARD</b> platform developed by <a href="/blog/tags/NHN/" target="_self">NHN</a>.  
</p><p><b>Spock Proxy</b> is a Sharding platform designed based on MySQL Proxy. In MySQL Proxy, you can execute the Lau scrip code, which is written by a developer before and after performing SQL.  The primary purpose of using MySQL Proxy is to analyze and modify SQL. To use Spock Proxy, you need to create a MySQL database to manage the information about shards and how the data should be distributed.  The row is a rule for Sharding.
</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/507/323/specifying-sharding-rules-in-spock-proxy.png" alt="Figure 1: Specifying Sharding rules in Spock Proxy." width="477" height="219" editor_component="image_link" /><br /></p><p style="text-align: center;"><span class="Apple-style-span" style="font-family: Arial; font-size: 12px; "><strong>Figure 1: Specifying Sharding rules in Spock Proxy.</strong></span></p><p><b>CUBRID SHARD</b> is the Sharding platform for CUBRID. The uniqueness of CUBRID SHARD is that it can also be used with MySQL as well as Oracle. It is set to be launched in the first half of 2012, and is planned to be used for processing the meta information database system of <a href="http://ndrive.naver.com/index.nhn" target="_self" style="font-weight: bold; ">NDrive</a>&nbsp;service, the cloud storage system developed by NHN. 
</p><p>The following table shows a summary of a comparison between Spock Proxy and CUBRID SHARD.</p>

<p style="text-align: center;"><strong>Table 1 Comparison between Spock Proxy and CUBRID SHARD</strong></p>
<table style="margin:0 auto">
<thead>
<tr><td>&nbsp;</td><td>Spock Proxy</td>
<td>CUBRID SHARD</td></tr>
</thead>
<tbody>
<tr>
<td>Sharding rule store</td><td>DBMS Table</td><td>Configuration file</td></tr><tr><td>How to create Shard keys</td><td>Modulo</td><td class=""><ul><li>Modulo</li><li>Developer's own sharding strategy provided in a library</li></ul></td></tr><tr><td>How to find a Shard key</td><td>SQL parsing</td><td class="">Using HINT</td></tr><tr><td>Strength</td><td class="">No need to change SQL</td><td class=""><ul><li>Supports CURBID, MySQL, and Oracle</li><li>Higher performance</li></ul></td></tr><tr><td>Weakness</td><td class=""><ul><li>Lower performance due to extra SQL parsing</li><li>Supports MySQL only</li></ul></td><td class="">Requires the change to SQL queries to insert sharding HINT</td></tr></tbody></table>

<p><b>Spock Proxy</b> stores Sharding rules in the table in MySQL database (the rest '<b>universal_db</b>'). The SQL received from an application server is parsed, and checks whether the query has <b>shard keys</b>.  If shard keys are provided, the MySQL instance will be identified according to the standard recorded in <b>universal_db</b>, then SQL will be relayed to that MySQL instance.&nbsp;When using this method, you do not need to describe information related to shard keys in SQL, unlike in CUBRID SHARD.  Therefore, if you did not use Sharding before for your coding, but recently had to use due to the data increase, you may use Spock Proxy which will work without requiring you to change the SQL in your application.  Note that this is limited to cases where there is no need to change the schema for Sharding, or when Sharding can be applied without changing the SQL that you use.  However, the method used to find Shard after parsing SQL, as used by Spock Proxy, has weaknesses in terms of performance.  It could lead to unnecessary work, as SQL should be parsed twice: once by Spock Proxy to determine the MySQL instance, then by MySQL itself.</p><p>In CUBRID SHARD, <b>HINT</b> is used which allows to avoid parsing SQL twice. Suppose there is a table as follows: 
</p>

<table style="margin:0 auto">
<thead>
	<tr><td colspan="3">student</td></tr>
</thead>
<tbody>
	<tr><td>student_no</td><td>name</td><td>age</td></tr>
	<tr><td>...</td><td>...</td><td>...</td></tr>
</tbody></table>

<p>To use the <b>student_no</b> column data as a <i>shard key</i>, an application server sends the following prepared SQL to  CUBRID SHARD.</p><p></p><div editor_component="code_highlighter" code_type="Sql" file_path="" description="" first_line="1" collapse="false" nogutter="true" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">SELECT student_no, name, age FROM student WHERE student_no = /*+ SHARD_KEY */ ?</div><p></p>
<p>CUBRID SHARD shows that if a HINT displays <span style="font-family: monospace; ">/*+ SHARD_KEY */</span> in SQL, the column data with the corresponding HINT can be used as a <b>Shard key</b>. It then reads the <b>student_no</b> value, which follows the hint, and identifies RDBMS based on the configuration file and transmits the corresponding query. As such, the benefit of using HINT is that you can improve processing efficiency by avoiding parsing SQL twice, and react to various RDBMS without violating the database location abstract.  
</p><p></p><ol><li>CUBRID SHARDING provides various HINTs, in addition to <span style="font-family: monospace; ">/*+ SHARD_KEY */</span>.</li><li>Typically, there is  <span style="font-family: monospace; ">/*+ SHARD_ID(</span><em><span style="font-family: monospace; ">__id__</span></em><span style="font-family: monospace; ">) */</span>, a HINT that allows you to find a special shard.</li><li>The&nbsp;<span style="font-family: monospace; ">/*+ SHARD_VAL(</span><em><span style="font-family: monospace; ">__shard_key_val__</span></em><span style="font-family: monospace; ">) */&nbsp;</span>HINT can also play a role in finding a special shard for tables which have no shard keys. While this HINT is the same in that it searches for tables that have no specific shard keys, it configures a value for shard key column directly without choosing a shard, and selects the shard according to the internal rules of the middleware.</li></ol><p></p><p>Unlike Spock Proxy where Sharding rules are inserted into a database table,&nbsp;in CUBRID SHARD&nbsp;Sharding rules are specified in the configuration file. If there are three access addresses for actual RDBMS storage, you should specify DB addresses to CUBRID SHARD as follows.</p><p></p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">0 shardDB shardNODE1:3306<br />1 shardDB shardNODE2:3306<br />2 shardDB shardNODE3:3306<br />3 shardDB shardNODE4:3306</div><p></p><p></p><p></p>
<p>If you want to use the <b>Modulo</b> method, write the corresponding value in the configuration file as below.</p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="true" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">SHARD_KEY_MODULAR = 256</div><p></p>
<p>In addition, specify <span style="font-family: monospace; ">[MIN..MAX]</span> according to the value generated from <span style="font-family: monospace; ">SHARD_KEY_MODULAR</span>, and describe which shard to send the corresponding query to.<br /></p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">#min max shard_id<br />0 &nbsp; &nbsp;63 &nbsp; 0<br />64 &nbsp; 127 &nbsp;1<br />128 &nbsp;191 &nbsp;2<br />192 &nbsp;255 &nbsp;3</div><p></p><p></p><p></p>
<p>If you need a more subtle method than <b>Modulo</b>, you can create program code of your own that calculates the Shard ID for Shard keys.</p><p></p><p></p><div editor_component="code_highlighter" code_type="Plain" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">SHARD_KEY_LIBRARY_NAME = libshardkeyid.so<br />SHARD_FUNCTION_NAME = user_get_shard_key</div><p></p><p></p><p></p>
<p>As shown in the above example, you can register your own&nbsp;library which will&nbsp;calculate the&nbsp;Shard ID&nbsp;logic.</p><p>The common weakness of both Spock Proxy and CUBRID SHARD is that they both require additional network IO time for each additional hop&nbsp;because they are implemented as a middle tier.</p><p>The following figure displays a general process of internal execution in CUBRID SHARD, which is performed when a developer executes a query. When a developer executes a query, the query is analyzed by the DB shard middleware, which determines to which shard it will be sent.  Then the query is transmitted to the selected shard, and finally the middleware delivers the response to the client.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/507/323/cubrid-shard-process.png" alt="Figure 2: CUBRID SHARD process." width="648" height="510" editor_component="image_link" /><br /></p><p style="text-align: center;"><span class="Apple-style-span" style="font-family: Arial; font-size: 12px; "><strong>Figure 2: CUBRID SHARD process.</strong></span></p><h2>Gizzard</h2><p></p><p>Gizzard is a Sharding platform developed by <a href="/blog/tags/Twitter/" target="_self">Twitter</a>. It is also a middle tier just like Spock Proxy and CUBRID SHARD. However, its usage and architecture are quite different from Spock Proxy or CUBRID SHARD.</p><p>The following figure shows how the data can be shared between several databases deploying two units of Gizzard.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/507/323/gizzard-deployment-diagram.png" alt="gizzard-deployment-diagram.png" width="390" height="450" editor_component="image_link" /><br /></p><p style="text-align: center;"><span class="Apple-style-span" style="font-family: Arial; font-size: 12px; "><strong>Figure 3: Gizzard deployment diagram.</strong></span></p><p>In this case, the interface being used by an application server is <b>Thrift</b>, an RPC protocol, not JDBC. Therefore, it is similar to&nbsp;<b>DBGW&nbsp;</b>platform&nbsp;developed by NHN. When the schema of a storage changes, Gizzard may also need modifications. While it can be a constraint, it could also open up access not only to RDBMS, but also to various other databases (e.g. Lucene).</p><p>Gizzard is written based on Scala, and you can expand its functions by adding Scala codes as needed. Instead of viewing it as a complete product, we recommend that you download the source and modify it to suit your needs. 
</p><p>The biggest advantage of Gizzard is that you can perform hotspot response and database migration in the middle tier platform level.  For example, Gizzard provides the direct replication feature, as shown in the following figure. 
</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/507/323/replication-feature-of-gizzard.png" alt="Figure 4: The replication feature of Gizzard." width="365" height="298" editor_component="image_link" /><br /></p><p style="text-align: center;"><span class="Apple-style-span" style="font-family: Arial; font-size: 12px; "><strong>Figure 4: The replication feature of Gizzard.</strong></span></p><p>Spock Proxy or  CUBRID SHARD do not offer this feature, as they do not need it.  CUBRID, MySQL, and Oracle have their own replication feature, thus they do not need to offer the feature from the middle tier. 
</p><p>The replication feature provided by Gizzard is very simple - send each request to several replicas -  but cannot handle variety of requests that may occur while running the replication feature.  However, it can be useful when using a database without the replication feature.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/507/323/migration-feature-of-gizzard.png" alt="Figure 5: The migration feature of Gizzard." width="365" height="396" editor_component="image_link" /><br /></p><p style="text-align: center;"><span class="Apple-style-span" style="font-family: Arial; font-size: 12px; "><strong>Figure 5: The migration feature of Gizzard.</strong></span></p><p>As shown in the figure above, it offers the replication feature which does not require a service halt.  When migrating a certain database, the feature replicates the details of a database storage before replication configuration, after allowing the new data to be written in two locations by configuring the replication.  This approach, of course, cannot be used on RDBMS due to consistency issue. 
</p><h2>Limitations of Sharding</h2><p>Sharding, on the other hand, also has its own limitations. Typical constraints of Sharding are as follows: 
</p><ul><li>It cannot perform JOIN operations for two or more Shardings. 
</li><li>auto increment (serial) values can vary depending on Sharding.  
</li><li>last_insert_id() value is no more valid. 
</li><li><b>shard key</b> column value must not be updated; requires delete, then insert.
</li><li>does not allow to access two or more Shards from one transaction. 
</li></ul><p>When using Sharding, therefore, it is important that you right perform data modeling and schema design to prevent the above constraint issues.</p><p>To learn more about Sharding and other features of CUBRID I suggest you to see the Slideshare presentation at&nbsp;<a href="http://www.slideshare.net/cubrid/growing-in-the-wild-the-story-by-cubrid-database-developers" target="_self">http://www.slideshare.net/cubrid/growing-in-the-wild-the-story-by-cubrid-database-developers</a>.</p><p><span class="Apple-style-span" style="line-height: normal; ">By&nbsp;Jeon Won Hee, Senior Software Engineer at CUBRID&nbsp;DBMS Development Lab,&nbsp;NHN Corporation.</span></p>]]></description>
                        <pubDate>Tue, 10 Apr 2012 15:40:32 +0900</pubDate>
                        <category>Sharding</category>
                        <category>CUBRID SHARD</category>
                        <category>Spock Proxy</category>
                        <category>MySQL</category>
                        <category>Gizzard</category>
                                </item>
        										        <item>
            <title>How to Analyze Java Thread Dumps</title>
            <dc:creator>Tae Jin Gu</dc:creator>
            <link>http://www.cubrid.org/blog/dev-platform/how-to-analyze-java-thread-dumps/</link>
            <guid isPermaLink="true">http://www.cubrid.org/blog/dev-platform/how-to-analyze-java-thread-dumps/</guid>
                        <comments>http://www.cubrid.org/blog/dev-platform/how-to-analyze-java-thread-dumps/#comment</comments>
                                    <description><![CDATA[<p></p><p>When there is an obstacle, or when a Java based Web application is running much slower than expected,&nbsp;we need to use <b>thread dumps</b>. If thread dumps feel like very complicated to you,&nbsp;this article may help you very much. Here I will explain what threads are in Java, their types, how they are created, how to manage them, how you can dump threads from a running application, and finally how you can analyze them and determine the bottleneck or blocking threads. This article is a result of long&nbsp;experience in&nbsp;Java application debugging.</p><h2>Java and Thread</h2><p>A web server uses tens to hundreds of threads to process a large number of concurrent users. If two or more threads utilize the same resources, a <i>contention</i> between the threads is inevitable, and sometimes deadlock occurs.</p><p><b>Thread contention</b> is a status in which one thread is waiting for a lock, held by another thread, to be lifted. Different threads frequently access shared resources on a web application. For example, to record a log, the thread trying to record the log must obtain a lock and access the shared resources.</p><p><b>Deadlock</b> is a special type of thread contention, in which two or more threads are waiting for the other threads to complete their tasks in order to complete their own tasks.</p><p>Different issues can arise from thread contention. To analyze such issues, you need to use the <b>thread dump</b>. A thread dump will give you the information on the exact status of each thread.</p><h2>Background Information for Java Threads</h2><h3>Thread Synchronization</h3><p>A thread can be processed with other threads at the same time. In order to ensure compatibility when multiple threads are trying to use shared resources, one thread at a time should be allowed to access the shared resources by using <i>thread synchronization</i>.</p><p>Thread synchronization on Java can be done using <b>monitor</b>. Every Java object has a single monitor. The monitor can be owned by only one thread. For a thread to own a monitor that is owned by a different thread, it needs to wait in the wait queue until the other thread releases its monitor.</p><h3>Thread Status</h3><p>In order to analyze a thread dump, you need to know the status of threads. The statuses of threads are stated on java.lang.Thread.State.</p><p style="text-align: center;">&nbsp;<img src="http://www.cubrid.org/files/attach/images/220547/971/295/thread-state-diagram.png" alt="Figure 1: Thread Status." width="295" height="288" editor_component="image_link" />
</p><p style="text-align: center;"><b>Figure 1: Thread Status.</b></p><p></p><ul><li><b>NEW</b>: The thread is created but has not been processed yet.</li><li><b>RUNNABLE</b>: The thread is occupying the CPU and processing a task. (It may be in <span style="font-family: monospace; ">WAITING</span> status due to the OS's resource distribution.)</li><li><b>BLOCKED</b>: The thread is waiting for a different thread to release its lock in order to get the monitor lock.</li><li><b>WAITING</b>: The thread is waiting by using a <span style="font-family: monospace; ">wait, join</span> or <span style="font-family: monospace; ">park</span> method.</li><li><b>TIMED_WAITING</b>: The thread is waiting by using a <span style="font-family: monospace; ">sleep</span>, <span style="font-family: monospace; ">wait</span>, <span style="font-family: monospace; ">join</span> or <span style="font-family: monospace; ">park</span> method. (The difference from <span style="font-family: monospace; ">WAITING</span> is that the maximum waiting time is specified by the method parameter, and <i>WAITING</i> can be relieved by time as well as external changes.)&nbsp;</li></ul><p></p><h3>Thread Types</h3><p>Java threads can be divided into two:</p><p></p><ol><li>daemon threads;</li><li> and non-daemon threads.</li></ol><p></p><p><b>Daemon threads</b> stop working when there are no other non-daemon threads. Even if you do not create any threads, the Java application will create several threads by default. Most of them are daemon threads, mainly for processing tasks such as garbage collection or JMX.</p><p>A thread running the '<span style="font-family: monospace; ">static void main(String[] args)</span>’ method is created as a non-daemon thread, and when this thread stops working, all other daemon threads will stop as well. (The thread running this main method is called the <b>VM thread in HotSpot VM</b>.)</p><h2>Getting a Thread Dump</h2><p>We will introduce the three most commonly used methods. Note that there are many other ways to get a thread dump. A thread dump can only show the thread status at the time of measurement, so in order to see the change in thread status, it is recommended to extract them from 5 to 10 times with 5-second intervals.</p><h3>Getting a Thread Dump Using jstack</h3><p>In JDK 1.6 and higher, it is possible to get a thread dump on MS Windows using <b>jstack</b>.</p><p>Use PID via jps to check the PID of the currently running Java application process.</p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[user@linux ~]$ ups -v<br /><br />25780 RemoteTestRunner -Dfile.encoding=UTF-8<br />25590 sub.rmi.registry.RegistryImpl 2999 -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m<br />26300 sun.tools.jps.Jps -mlvV -Dapplication.home=/home1/user/java/jdk.1.6.0_24 -Xms8m</div><p></p><p>Use the extracted PID as the parameter of jstack to obtain a thread dump.</p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[user@linux ~]$ jstack -f5824&nbsp;</div><p></p><h3>A Thread Dump Using jVisualVM</h3><p>Generate a thread dump by using a program such as jVisualVM.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/thread-dump-using-jvisualvm.png" alt="Figure 2: &amp;nbsp;A Thread Dump Using visualvm." width="689" height="520" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 2: &nbsp;A Thread Dump Using visualvm.</b></p><p>The task on the left indicates the list of currently running processes. Click on the process for which you want the information, and select the thread tab to check the thread information in real time. Click the <span style="font-family: monospace; ">Thread Dump</span> button on the top right corner to get the thread dump file.</p><h3>Generating in a Linux Terminal</h3><p>Obtain the process <span style="font-family: monospace; ">pid</span> by using <span style="font-family: monospace; ">ps -ef</span> command to check the pid of the currently running Java process.</p><p></p><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[user@linux ~]$ ps - ef | grep java<br /><br />user &nbsp; &nbsp; &nbsp;2477 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp;0 Dec23 ? &nbsp; &nbsp; &nbsp; &nbsp; 00:10:45 ...<br />user &nbsp; &nbsp;25780 25361 &nbsp; 0 15:02 pts/3 &nbsp; &nbsp;00:00:02 ./jstatd -J -Djava.security.policy=jstatd.all.policy -p 2999<br />user &nbsp; &nbsp;26335 25361 &nbsp; 0 15:49 pts/3 &nbsp; &nbsp;00:00:00 grep java</div><p></p><p>Use the extracted pid as the parameter of <span style="font-family: monospace; ">kill –SIGQUIT(3)</span> to obtain a thread dump.</p><h2>Thread Information from the Thread Dump File</h2>

<pre><span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">"pool-1-thread-13"</span> <span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">prio=6</span> <span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">tid=0x000000000729a000 nid=0x2fb4</span> <span style="background-color: rgb(147, 52, 216); color: rgb(255, 255, 255); ">runnable [0x0000000007f0f000] java.lang.Thread.State: RUNNABLE</span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.net.SocketInputStream.socketRead0(Native Method)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.net.SocketInputStream.read(SocketInputStream.java:129)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">- locked &lt;0x0000000780b7e688&gt; (a java.io.InputStreamReader)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.io.InputStreamReader.read(InputStreamReader.java:167)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.io.BufferedReader.fill(BufferedReader.java:136)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.io.BufferedReader.readLine(BufferedReader.java:299)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">- locked &lt;0x0000000780b7e688&gt; (a java.io.InputStreamReader)
</span></span>
              <span style="background-color: rgb(142, 142, 142); color: rgb(255, 255, 255); "><span style="color: rgb(0, 0, 0); ">at java.io.BufferedReader.readLine(BufferedReader.java:362)</span></span></pre>

<ul><li><span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">Thread name</span>: When using Java.lang.Thread class to generate a thread, the thread will be named Thread-(Number), whereas when using java.util.concurrent.ThreadFactory class, it will be named pool-(number)-thread-(number).</li><li><span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">Priority</span>: Represents the priority of the threads.</li><li><span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">Thread ID</span>: Represents the unique ID for the threads. (Some useful information, including the CPU usage or memory usage of the thread, can be obtained by using thread ID.)</li><li><span style="background-color: rgb(147, 52, 216); color: rgb(255, 255, 255); ">Thread status</span>: Represents the status of the threads.</li><li><span style="background-color: rgb(142, 142, 142); color: rgb(0, 0, 0); ">Thread callstack</span>: Represents the call stack information of the threads.&nbsp;</li></ul><h2>Thread Dump Patterns by Type</h2>

<h3>When Unable to Obtain a Lock (BLOCKED)</h3>

<p>This is when the overall performance of the application slows down because a thread is occupying the lock and prevents other threads from obtaining it. In the following example, <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">BLOCKED_TEST pool-1-thread-1</span> thread is running with &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); "><span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x0000000780a000b0</span></span>&gt; lock, while <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">BLOCKED_TEST pool-1-thread-2</span> and <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">BLOCKED_TEST pool-1-thread-3</span> threads are waiting to obtain &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); "><span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x0000000780a000b0</span></span>&gt; lock.</p>

<p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/when-unable-to-obtain-lock.png" alt="Figure 3: A thread blocking other threads" width="581" height="84" editor_component="image_link" /></p><p style="text-align: center;"><b>Figure 3: A thread blocking other threads.</b>&nbsp;</p>

<pre>"BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000]
   java.lang.Thread.State: <span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">RUNNABLE</span>
                at java.io.FileOutputStream.writeBytes(Native Method)
                at java.io.FileOutputStream.write(FileOutputStream.java:282)
                at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
                at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
                - locked &lt;0x0000000780a31778&gt; (a java.io.BufferedOutputStream)
                at java.io.PrintStream.write(PrintStream.java:432)
                - locked &lt;0x0000000780a04118&gt; (a java.io.PrintStream)
                at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
                at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
                at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85)
                - locked &lt;0x0000000780a040c0&gt; (a java.io.OutputStreamWriter)
                at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168)
                at java.io.PrintStream.newLine(PrintStream.java:496)
                - locked &lt;0x0000000780a04118&gt; (a java.io.PrintStream)
                at java.io.PrintStream.println(PrintStream.java:687)
                - locked &lt;0x0000000780a04118&gt; (a java.io.PrintStream)
                at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44)
                - locked &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); "><span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x0000000780a000b0</span></span>&gt; (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
                - &lt;0x0000000780a31758&gt; (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

"BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000]
   java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43)
                - waiting to lock &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); "><span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x0000000780a000b0</span></span>&gt; (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
                - &lt;0x0000000780b0c6a0&gt; (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

"BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000]
   java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:42)
                - waiting to lock &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); "><span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x0000000780a000b0</span></span>&gt; (a com.nbp.theplatform.threaddump.ThreadBlockedState)
                at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
                - &lt;0x0000000780b0e1b8&gt; (a java.util.concurrent.locks.ReentrantLock$NonfairSync)</pre>


<h3>When in Deadlock Status</h3>

<p>This is when <i>thread A</i> needs to obtain <i>thread B</i>'s lock to continue its task, while <i>thread B</i> needs to obtain <i>thread A</i>'s lock to continue its task. In the thread dump, you can see that <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">DEADLOCK_TEST-1 thread</span> has <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x00000007d58f5e48</span> lock, and is trying to obtain <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); "><span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">0x00000007d58f5e60</span></span> lock. You can also see that <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">DEADLOCK_TEST-2 thread</span> has <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); "><span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">0x00000007d58f5e60</span></span> lock, and is trying to obtain <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); "><span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">0x00000007d58f5e78</span></span> lock. Also, <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">DEADLOCK_TEST-3 thread</span> has <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); "><span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">0x00000007d58f5e78</span></span> lock, and is trying to obtain <span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x00000007d58f5e48</span> lock. As you can see, each thread is waiting to obtain another thread's lock, and this status will not change until one thread discards its lock.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/when-in-deadlock-status.png" alt="Figure 4: Threads in a Deadlock status" width="580" height="91" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 4: Threads in a Deadlock status.</b></p>

<pre>"DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000]
   java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                - waiting to lock &lt;<span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">0x00000007d58f5e60</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                - locked &lt;<span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x00000007d58f5e48</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

   Locked ownable synchronizers:
                - None

"DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000]
   java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                - waiting to lock &lt;<span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">0x00000007d58f5e78</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                - locked &lt;<span style="background-color: rgb(153, 220, 255); color: rgb(0, 0, 0); ">0x00000007d58f5e60</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

   Locked ownable synchronizers:
                - None

"DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000]
   java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197)
                - waiting to lock &lt;<span style="background-color: rgb(255, 167, 0); color: rgb(255, 255, 255); ">0x00000007d58f5e48</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182)
                - locked &lt;<span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); ">0x00000007d58f5e78</span>&gt; (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor)
                at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135)

   Locked ownable synchronizers:
                - None
</pre>

<h3>When Continuously Waiting to Receive Messages from a Remote Server</h3>

<p>The thread appears to be normal, since its state keeps showing as <span style="background-color: rgb(166, 255, 77); color: rgb(0, 0, 0); "><span style="background-color: rgb(147, 52, 216); color: rgb(255, 255, 255); ">RUNNABLE</span></span>.&nbsp;However, when you align the thread dumps chronologically, you can see that <span style="font-family: monospace; ">socketReadThread thread</span> is waiting infinitely to read the socket.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/when-continuosly-waiting-to-receive-message-from-remote-server.png" alt="Figure 5: Continuous Waiting Status" width="578" height="33" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 5: Continuous Waiting Status.</b></p>

<pre>"socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000]
   java.lang.Thread.State: <span style="background-color: rgb(147, 52, 216); color: rgb(255, 255, 255); ">RUNNABLE</span>
                at java.net.SocketInputStream.socketRead0(Native Method)
                at java.net.SocketInputStream.read(SocketInputStream.java:129)
                at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
                at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
                at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
                - locked &lt;0x00000007d78a2230&gt; (a java.io.InputStreamReader)
                at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107)
                - locked &lt;0x00000007d78a2230&gt; (a java.io.InputStreamReader)
                at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93)
                at java.io.InputStreamReader.read(InputStreamReader.java:151)
                at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27)
                at java.lang.Thread.run(Thread.java:662)</pre>

<h3>When Waiting</h3>

<p>The thread is maintaining <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">WAIT</span> status. In the thread dump, <span style="font-family: monospace; ">IoWaitThread thread</span> keeps waiting to receive a message from <span style="font-family: monospace; ">LinkedBlockingQueue</span>. If there continues to be no message for LinkedBlockingQueue, then the thread status will not change.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/when-waiting.png" alt="Figure 6: Waiting status" width="580" height="35" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 6: Waiting status.</b></p><pre>"IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000]
   java.lang.Thread.State: <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">WAITING</span> (parking)
                at sun.misc.Unsafe.park(Native Method)
                - parking to wait for  &lt;0x00000007d5c45850&gt; (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
                at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
                at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
                at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440)
                at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629)
                at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89)
                at java.lang.Thread.run(Thread.java:662)
</pre>

<h3>When Thread Resources Cannot be Organized Normally</h3><p>Unnecessary threads will pile up when thread resources cannot be organized normally. If this occurs, it is recommended to monitor the thread organization process or check the conditions for thread termination.</p><p style="text-align: center;"><img src="http://www.cubrid.org/files/attach/images/220547/971/295/when-thread-resources-cannot-be-organized-normally.png" alt="Figure 7: Unorganized Threads" width="678" height="193" editor_component="image_link" /><br /></p><p style="text-align: center;"><b>Figure 7: Unorganized Threads.</b></p><h2>How to Solve Problems by Using Thread Dump</h2><h3>Example 1: When the CPU Usage is Abnormally High</h3><p></p><ol><li>Extract the thread that has the highest CPU usage.<br /><div editor_component="code_highlighter" code_type="Bash" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;">[user@linux ~]$ ps -mo pid.lwp.stime.time.cpu -C java<br /><br />&nbsp; &nbsp; &nbsp;PID &nbsp; &nbsp; &nbsp; &nbsp; LWP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;STIME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TIME &nbsp; &nbsp; &nbsp; &nbsp;%CPU<br />10029 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - &nbsp; &nbsp; &nbsp; &nbsp; Dec07 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;00:02:02 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 99.5<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- &nbsp; &nbsp; &nbsp; 10039 &nbsp; &nbsp; &nbsp; &nbsp;Dec07 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;00:00:00 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0.1<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- &nbsp; &nbsp; &nbsp; 10040 &nbsp; &nbsp; &nbsp; &nbsp;Dec07 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;00:00:00 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 95.5</div><p>From the application, find out which thread is using the CPU the most.</p><p>Acquire the <i>Light Weight Process</i> (LWP) that uses the CPU the most and convert its unique number (10039) into a hexadecimal number (0x2737).</p></li>
<li><p>After acquiring the thread dump, check the thread's action.</p><p>Extract the thread dump of an application with a PID of 10029, then find the thread with an <span style="font-family: monospace; ">nid of 0x2737</span>.</p>
<pre>"NioProcessor-2" prio=10 tid=0x0a8d2800 nid=0x2737 runnable [0x49aa5000]
java.lang.Thread.State: RUNNABLE
                at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
                at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
                at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
                at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
                - locked &lt;0x74c52678&gt; (a sun.nio.ch.Util$1)
                - locked &lt;0x74c52668&gt; (a java.util.Collections$UnmodifiableSet)
                - locked &lt;0x74c501b0&gt; (a sun.nio.ch.EPollSelectorImpl)
                at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
                at external.org.apache.mina.transport.socket.nio.NioProcessor.select(NioProcessor.java:65)
                at external.org.apache.mina.common.AbstractPollingIoProcessor$Worker.run(AbstractPollingIoProcessor.java:708)
                at external.org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:51)
                at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                at java.lang.Thread.run(Thread.java:662)
</pre>
<p>Extract thread dumps several times every hour, and check the status change of the threads to determine the problem.</p></li></ol>

<h3>Example 2: When the Processing Performance is Abnormally Slow &nbsp;</h3>

<p>After acquiring thread dumps several times, find the list of threads with <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> status.</p>

<pre>" DB-Processor-13" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f000]
java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
                - waiting to lock &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">0xe0375410</span>&gt; (a beans.ConnectionPool)
                at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
                at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)

"DB-Processor-14" daemon prio=5 tid=0x003edf98 nid=0xca waiting for monitor entry [0x000000000825f020]
java.lang.Thread.State: <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> (on object monitor)
                at beans.ConnectionPool.getConnection(ConnectionPool.java:102)
                - waiting to lock &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">0xe0375410</span>&gt; (a beans.ConnectionPool)
                at beans.cus.ServiceCnt.getTodayCount(ServiceCnt.java:111)
                at beans.cus.ServiceCnt.insertCount(ServiceCnt.java:43)

" DB-Processor-3" daemon prio=5 tid=0x00928248 nid=0x8b waiting for monitor entry [0x000000000825d080]
java.lang.Thread.State: <span style="background-color: rgb(147, 52, 216); color: rgb(255, 255, 255); ">RUNNABLE</span>
                at oracle.jdbc.driver.OracleConnection.isClosed(OracleConnection.java:570)
                - waiting to lock &lt;0xe03ba2e0&gt; (a oracle.jdbc.driver.OracleConnection)
                at beans.ConnectionPool.getConnection(ConnectionPool.java:112)
                - locked &lt;0xe0386580&gt; (a java.util.Vector)
                - locked &lt;0xe0375410&gt; (a beans.ConnectionPool)
                at beans.cus.Cue_1700c.GetNationList(Cue_1700c.java:66)
                at org.apache.jsp.cue_1700c_jsp._jspService(cue_1700c_jsp.java:120)
</pre>

<p>Acquire the list of threads with <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> status after getting the thread dumps several times.</p><p>If the threads are BLOCKED, extract the threads related to the lock that the threads are trying to obtain.</p><p>Through the thread dump, you can confirm that the thread status stays <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> because &lt;<span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">0xe0375410</span>&gt; lock could not be obtained. This problem can be solved by analyzing stack trace from the thread currently holding the lock.</p><p>There are two reasons why the above pattern frequently appears in applications using DBMS. The first reason is <b>inadequate configurations</b>. Despite the fact that the threads are still working, they cannot show their best performance because the configurations for DBCP and the like are not adequate. If you extract thread dumps multiple times and compare them, you will often see that some of the threads that were BLOCKED previously are in a different state.</p><p>The second reason is the <b>abnormal connection</b>. When the connection with DBMS stays abnormal, the threads wait until the time is out. In this case, even after extracting the thread dumps several times and comparing them, you will see that the threads related to DBMS are still in a BLOCKED state. By adequately changing the values, such as the timeout value, you can shorten the time in which the problem occurs.</p><h2>Coding for Easy Thread Dump</h2><h3>Naming Threads</h3><p>When a thread is created using <span style="font-family: monospace; ">java.lang.Thread</span> object, the thread will be named <span style="font-family: monospace; ">Thread-(Number)</span>. When a thread is created using <span style="font-family: monospace; ">java.util.concurrent.DefaultThreadFactory</span> object, the thread will be named <span style="font-family: monospace; ">pool-(Number)-thread-(Number)</span>. When analyzing tens to thousands of threads for an application, if all the threads still have their default names, analyzing them becomes very difficult, because it is difficult to distinguish the threads to be analyzed.</p><p>Therefore, you are recommended to develop the habit of naming the threads whenever a new thread is created.&nbsp;</p><p>When you create a thread using <span style="font-family: monospace; ">java.lang.Thread</span>, you can give the thread a custom name by using the creator parameter.</p><p></p><div editor_component="code_highlighter" code_type="Java" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;"><p>public Thread(Runnable target, String name);<br />public Thread(ThreadGroup group, String name);<br />public Thread(ThreadGroup group, Runnable target, String name);<br />public Thread(ThreadGroup group, Runnable target, String name, long stackSize);</p></div><p></p><p></p><p>When you create a thread using <span style="font-family: monospace; ">java.util.concurrent.ThreadFactory</span>, you can name it by generating your own <span style="font-family: monospace; ">ThreadFactory</span>. If you do not need special functionalities, then you can use <span style="font-family: monospace; ">MyThreadFactory</span> as described below:</p><p></p><div editor_component="code_highlighter" code_type="Java" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;"><p>import java.util.concurrent.ConcurrentHashMap;<br />import java.util.concurrent.ThreadFactory;<br />import java.util.concurrent.atomic.AtomicInteger;<br /><br />public class MyThreadFactory implements ThreadFactory {<br />&nbsp; private static final ConcurrentHashMap&lt;String, AtomicInteger&gt; POOL_NUMBER =<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new ConcurrentHashMap&lt;String, AtomicInteger&gt;();<br />&nbsp; private final ThreadGroup group;<br />&nbsp; private final AtomicInteger threadNumber = new AtomicInteger(1);<br />&nbsp; private final String namePrefix;<br />&nbsp;<br />&nbsp; public MyThreadFactory(String threadPoolName) {<br />&nbsp; &nbsp; &nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp; if (threadPoolName == null) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new NullPointerException("threadPoolName");<br />&nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp;&nbsp;</p><p>&nbsp; &nbsp; &nbsp; POOL_NUMBER.putIfAbsent(threadPoolName, new AtomicInteger());<br />&nbsp; &nbsp; &nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp; SecurityManager securityManager = System.getSecurityManager();<br />&nbsp; &nbsp; &nbsp; group = (securityManager != null) ? securityManager.getThreadGroup() :<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.currentThread().getThreadGroup();<br />&nbsp; &nbsp; &nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp; AtomicInteger poolCount = POOL_NUMBER.get(threadPoolName);<br /><br />&nbsp; &nbsp; &nbsp; if (poolCount == null) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; namePrefix = threadPoolName + " pool-00-thread-";<br />&nbsp; &nbsp; &nbsp; } else {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; namePrefix = threadPoolName + " pool-" + poolCount.getAndIncrement() + "-thread-";<br />&nbsp; &nbsp; &nbsp; }<br />&nbsp; }<br />&nbsp;<br />&nbsp; public Thread newThread(Runnable runnable) {<br />&nbsp; &nbsp; &nbsp; Thread thread = new Thread(group, runnable, namePrefix + threadNumber.getAndIncrement(), 0);<br /><br />&nbsp; &nbsp; &nbsp; if (thread.isDaemon()) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread.setDaemon(false);<br />&nbsp; &nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; &nbsp; if (thread.getPriority() != Thread.NORM_PRIORITY) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; thread.setPriority(Thread.NORM_PRIORITY);<br />&nbsp; &nbsp; &nbsp; }<br /><br />&nbsp; &nbsp; &nbsp; return thread;<br />&nbsp; }<br />}</p></div><h3>Obtaining More Detailed Information by Using MBean</h3><p>You can obtain <span style="font-family: monospace; ">ThreadInfo</span> objects using <span style="font-family: monospace; ">MBean</span>. You can also obtain more information that would be difficult to acquire via thread dumps, by using ThreadInfo.</p><p></p><div editor_component="code_highlighter" code_type="Java" file_path="" description="" first_line="1" collapse="false" nogutter="false" nocontrols="false" style="border: #666666 1px dotted; border-left: #22aaee 5px solid; padding: 5px; background: #FAFAFA url('./modules/editor/components/code_highlighter/code.png') no-repeat top right;"><p>ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();<br />long[] threadIds = mxBean.getAllThreadIds();<br />ThreadInfo[] threadInfos =<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mxBean.getThreadInfo(threadIds);<br /><br />for (ThreadInfo threadInfo : threadInfos) {<br />&nbsp; System.out.println(<br />&nbsp; &nbsp; &nbsp; threadInfo.getThreadName());<br />&nbsp; System.out.println(<br />&nbsp; &nbsp; &nbsp; threadInfo.getBlockedCount());<br />&nbsp; System.out.println(<br />&nbsp; &nbsp; &nbsp; threadInfo.getBlockedTime());<br />&nbsp; System.out.println(<br />&nbsp; &nbsp; &nbsp; threadInfo.getWaitedCount());<br />&nbsp; System.out.println(<br />&nbsp; &nbsp; &nbsp; threadInfo.getWaitedTime());<br />}&nbsp;</p></div><p>You can acquire the amount of time that the threads <span style="background-color: rgb(228, 255, 117); color: rgb(0, 0, 0); ">WAITed</span> or were <span style="background-color: rgb(255, 0, 0); color: rgb(255, 255, 255); ">BLOCKED</span> by using the method in ThreadInfo, and by using this you can also obtain the list of threads that have been inactive for an abnormally long period of time.</p><h2>In Conclusion</h2><p>In this article I was concerned that for developers with a lot of experience in multi-thread programming, this material may be common knowledge, whereas for less experienced developers, I felt that I was skipping straight to thread dumps, without providing enough background information about the thread activities. This was because of my lack of knowledge, as I was not able to explain the thread activities in a clear yet concise manner. I sincerely hope that this article will prove helpful for many developers.</p><p></p><p>By Tae Jin Gu, Software Engineer at Web Platform Development Lab, NHN Corporation.</p>]]></description>
                        <pubDate>Thu, 16 Feb 2012 15:13:27 +0900</pubDate>
                        <category>Java</category>
                        <category>programming</category>
                        <category>Threads</category>
                        <category>Debugging</category>
                                    <slash:comments>3</slash:comments>
                    </item>
            </channel>
</rss>

