Posted
almost 12 years
ago
by
Dongsoon Choi
Developers often use a timer when developing an application. A timer is especially needed when you process a timeout for sessions. With the TimerWheel data structure, you can perform this type of task more efficiently than you would
... [More]
with java.util.Timer provided by JDK. However, there are some limitations which I will cover in this article. I will also explain how I used TimerWheel in multiple projects in our company.
Efforts to Make a More Efficient Timer
When you are developing an application, you will need to use a timer frequently. If you use an application with Java, you can implement a timer easily by using the java.util.Timer provided by JDK. But when a timer needs to be used very frequently, it is difficult to get satisfactory performance with java.util.Timer alone. This is because of the synchronization that occurs when you add or delete a timertask.
In 2010, when I was involved in a project at NHN to develop a Comet-based communication server, I applied a data structure called TimingWheel. TimingWheel is a timer implementation approach that can achieve much better performance than java.util.Timer in some cases. But it is not possible to apply TimingWheel to every timer requirement.
At its core, TimingWheel is a data structure required to implement a timer used to process data retransfer and protocol recovery at the network protocol level. But it can be used for a variety of purposes depending on how it is applied.
When I was developing a Comet-based communication server, I considered using TimingWheel when I was seeking an efficient method to process tasks, such as ping/pong or timeout, that needed to be performed at a certain interval for each session (connection). At that time, the maximum number of sessions was 10,000, and as it was necessary to process various kinds of timeout, including ping/pong, re-connection and session expiration, for each session, I could not meet this requirement with java.util.Timer or Quartz alone.
For this reason, I applied TimingWheel to process timeout more efficiently. TimingWheel is a data structure that enables you to handle a timer process at O(1) time complexity.
Basic Structure and Terms of TimingWheel
As shown in Figure 1, the basic structure of TimingWheel is a fixed-size circular array:
Figure 1: The Basic Structure of TimingWheel (http://www.transitmagazine.com/lib0071.html).
Each bucket of the array is called a time slot, and contains a list of tasks to be processed when a timeout occurs. As its basic operation, TimingWheel circulates time slots at a slot interval, processing the content contained in the relevant time slot.
Figure 2 below shows the situation in which when the slot interval is 50 ms, the timeout job that will occur after 200 ms is registered (registration of a timeout job with the time interval of 200 ms).
Figure 2. The Process of Registering a Timeout Job (http://www.transitmagazine.com/lib0071.html).
As the slot interval is 50 ms, a timeout job for a timer that will occur after 200 ms should be stored in the slot that is located after four slots from the current cursor. In this way, you can store a timeout job with O(1). As it moves to the next slot at a 50 ms interval, the cursor will arrive at the time slot that is located after four slots from its origin after 200 ms from the current time. If the cursor moves to the slot, TimingWheel will read the value of the time slot and process the timeout task. Whenever the cursor travels through the time slots, TimingWheel can process all the designated timeout tasks, and thus it is not necessary to conduct an additional inspection for timer processing during a timeout job, or in the logic used to process a timeout job. Therefore, you can implement a timer within the time complexity of O(1).
Code 1 below shows the method of calculating the time slot to store a timeout job.
Code 1: TargetSlot Calculation Method.
targetSlot = ( currentSlot + (timeInterval / slotInterval)) % timeSlotCount
In the project where TimingWheel was employed, I also used the Code 1 method to implement TimingWheel. Figure 3 shows a circular array which has been expressed more intuitively.
Figure 3: Operation of a Simple TimingWheel.
When I implemented TimingWheel in the project, I had a timeout job processed in a separate thread pool in order to have a separate thread to run TimingWheel and a thread to process a timeout job.
However, TimingWheel cannot be applied to every case in which a timer is required. As shown in Figure 2, there is a cap in max interval. If the number of time slots is 7 and the interval is 50 ms, as in Figure 2, you cannot register a value exceeding 350 ms.
If the interval is 1 second, you need a total of 4995 time slots (60*60 + 23*60 + 15), a huge memory requirement to process the time interval of 1h 23m 15s without any overflow. To address this problem, of course, you may use Hashed TimingWheel or Hierarchical TimingWheel. But as you can't use TimingWheel for every timer requirement, it is advised to implement TimingWheel after determining the appropriateness of implementing TimingWheel in your project.
Effects of TimingWheel
In addition to the Comet project conducted in 2010, I also took part in two other projects where TimingWheel was implemented.
First, I applied TimingWheel to a project in which when multiple timeout jobs had to be simultaneously performed, the CPU usage, which had normally been only 1-2%, reached 100%. This high CPU usage occurred because there were many timeout jobs to be executed simultaneously, but after applying TimingWheel, timeout jobs could be performed stably.
I also applied TimingWheel to a project for developing an HTML5-based game.
As Javascript of a browser runs based on a single thread, if you use many timers in the development of an HTML5 game, there will be a noticeable deterioration in game rendering.
In addition, as shown in Figure 4 below, HTML5 game engines, which are used in the development of games, provide a method for frame-based operation. If this method is used for timers in any area other than animation effects, the number of frames will drop due to excessive use of resources (see Figure 4).
Figure 4: Method of Frame Processing in HTML5 Game Engines.
As shown in C in Figure 5, if a timer that runs at 1-minute intervals uses OnAction, 3659 unnecessary calls will be wasted.
Figure 5: Examples of Unnecessary Use of Resources.
I applied TimingWheel to address this problem. I was able to meet the requirement with a single TimingWheel timer, and succeeded in maintaining the number of frames stably.
By Dongsoon Choi, Senior Software Engineer at Game Platform Development Center, NHN Corporation.
Reference
Implement lower timer granularity for retransmission of TCP: http://www.ibm.com/developerworks/aix/library/au-lowertime/index.html
Hashed and hierarchical timing wheels: efficient data structures for implementing a timer facility: http://dl.acm.org/citation.cfm?id=270876
PPT Document of Reference 2: http://ebookbrowse.com/timingwheels-ppt-d195376642
Real-Time Concepts for Embedded Systems (Chapter 11): http://www.transitmagazine.com/lib0069.html
[Less]
|
Posted
almost 12 years
ago
by
Dongsoon Choi
Developers often use a timer when developing an application. A timer is especially needed when you process a timeout for sessions. With the TimerWheel data structure, you can perform this type of task more efficiently than you would
... [More]
with java.util.Timer provided by JDK. However, there are some limitations which I will cover in this article. I will also explain how I used TimerWheel in multiple projects in our company.
Efforts to Make a More Efficient Timer
When you are developing an application, you will need to use a timer frequently. If you use an application with Java, you can implement a timer easily by using the java.util.Timer provided by JDK. But when a timer needs to be used very frequently, it is difficult to get satisfactory performance with java.util.Timer alone. This is because of the synchronization that occurs when you add or delete a timertask.
In 2010, when I was involved in a project at NHN to develop a Comet-based communication server, I applied a data structure called TimingWheel. TimingWheel is a timer implementation approach that can achieve much better performance than java.util.Timer in some cases. But it is not possible to apply TimingWheel to every timer requirement.
At its core, TimingWheel is a data structure required to implement a timer used to process data retransfer and protocol recovery at the network protocol level. But it can be used for a variety of purposes depending on how it is applied.
When I was developing a Comet-based communication server, I considered using TimingWheel when I was seeking an efficient method to process tasks, such as ping/pong or timeout, that needed to be performed at a certain interval for each session (connection). At that time, the maximum number of sessions was 10,000, and as it was necessary to process various kinds of timeout, including ping/pong, re-connection and session expiration, for each session, I could not meet this requirement with java.util.Timer or Quartz alone.
For this reason, I applied TimingWheel to process timeout more efficiently. TimingWheel is a data structure that enables you to handle a timer process at O(1) time complexity.
Basic Structure and Terms of TimingWheel
As shown in Figure 1, the basic structure of TimingWheel is a fixed-size circular array:
Figure 1: The Basic Structure of TimingWheel (http://www.transitmagazine.com/lib0071.html).
Each bucket of the array is called a time slot, and contains a list of tasks to be processed when a timeout occurs. As its basic operation, TimingWheel circulates time slots at a slot interval, processing the content contained in the relevant time slot.
Figure 2 below shows the situation in which when the slot interval is 50 ms, the timeout job that will occur after 200 ms is registered (registration of a timeout job with the time interval of 200 ms).
Figure 2. The Process of Registering a Timeout Job (http://www.transitmagazine.com/lib0071.html).
As the slot interval is 50 ms, a timeout job for a timer that will occur after 200 ms should be stored in the slot that is located after four slots from the current cursor. In this way, you can store a timeout job with O(1). As it moves to the next slot at a 50 ms interval, the cursor will arrive at the time slot that is located after four slots from its origin after 200 ms from the current time. If the cursor moves to the slot, TimingWheel will read the value of the time slot and process the timeout task. Whenever the cursor travels through the time slots, TimingWheel can process all the designated timeout tasks, and thus it is not necessary to conduct an additional inspection for timer processing during a timeout job, or in the logic used to process a timeout job. Therefore, you can implement a timer within the time complexity of O(1).
Code 1 below shows the method of calculating the time slot to store a timeout job.
Code 1: TargetSlot Calculation Method.
targetSlot = ( currentSlot + (timeInterval / slotInterval)) % timeSlotCount
In the project where TimingWheel was employed, I also used the Code 1 method to implement TimingWheel. Figure 3 shows a circular array which has been expressed more intuitively.
Figure 3: Operation of a Simple TimingWheel.
When I implemented TimingWheel in the project, I had a timeout job processed in a separate thread pool in order to have a separate thread to run TimingWheel and a thread to process a timeout job.
However, TimingWheel cannot be applied to every case in which a timer is required. As shown in Figure 2, there is a cap in max interval. If the number of time slots is 7 and the interval is 50 ms, as in Figure 2, you cannot register a value exceeding 350 ms.
If the interval is 1 second, you need a total of 4995 time slots (60*60 + 23*60 + 15), a huge memory requirement to process the time interval of 1h 23m 15s without any overflow. To address this problem, of course, you may use Hashed TimingWheel or Hierarchical TimingWheel. But as you can't use TimingWheel for every timer requirement, it is advised to implement TimingWheel after determining the appropriateness of implementing TimingWheel in your project.
Effects of TimingWheel
In addition to the Comet project conducted in 2010, I also took part in two other projects where TimingWheel was implemented.
First, I applied TimingWheel to a project in which when multiple timeout jobs had to be simultaneously performed, the CPU usage, which had normally been only 1-2%, reached 100%. This high CPU usage occurred because there were many timeout jobs to be executed simultaneously, but after applying TimingWheel, timeout jobs could be performed stably.
I also applied TimingWheel to a project for developing an HTML5-based game.
As Javascript of a browser runs based on a single thread, if you use many timers in the development of an HTML5 game, there will be a noticeable deterioration in game rendering.
In addition, as shown in Figure 4 below, HTML5 game engines, which are used in the development of games, provide a method for frame-based operation. If this method is used for timers in any area other than animation effects, the number of frames will drop due to excessive use of resources (see Figure 4).
Figure 4: Method of Frame Processing in HTML5 Game Engines.
As shown in C in Figure 5, if a timer that runs at 1-minute intervals uses OnAction, 3659 unnecessary calls will be wasted.
Figure 5: Examples of Unnecessary Use of Resources.
I applied TimingWheel to address this problem. I was able to meet the requirement with a single TimingWheel timer, and succeeded in maintaining the number of frames stably.
By Dongsoon Choi, Senior Software Engineer at Game Platform Development Center, NHN Corporation.
Reference
Implement lower timer granularity for retransmission of TCP: http://www.ibm.com/developerworks/aix/library/au-lowertime/index.html
Hashed and hierarchical timing wheels: efficient data structures for implementing a timer facility: http://dl.acm.org/citation.cfm?id=270876
PPT Document of Reference 2: http://ebookbrowse.com/timingwheels-ppt-d195376642
Real-Time Concepts for Embedded Systems (Chapter 11): http://www.transitmagazine.com/lib0069.html
[Less]
|
Posted
almost 12 years
ago
by
Soyoung Jeong
These days we can see virtualization technology everywhere in our daily life. In this article I will explain about the basic knowledge of virtualization, mainly with x86 architecture, the technology used for CPU, memory, and IO, as well as the trends
... [More]
of virtualization technology development.
Benefits of Server Virtualization
The universalization of virtual machines has brought many positive effects on computing environments and internet business. The most noticeable advantage of virtual machines is that they reduce server costs significantly. For example, many internet venture companies benefit from Amazon EC2. In addition to such cost merit, virtual machines also provide many benefits in terms of operation. They enable you to provide server infrastructure fast, and to control resources, such as memory size, remotely.
Since 2008, NHN has used virtual machines (VM) when a server is required for development/test purposes or, in some cases, to provide actual services. Ncloud Dev. Team at NHN released Ncloud, an integrated cloud solution service, in 2011, and has provided virtual servers both internally and externally.
The benefit of cloud solutions like Ncloud to developers is that it has universalized the application and use of servers. VMs enable you to get a server that you can use within a few minutes without any particular payment.
The field of servers is not the only place where such VMs are used. Many general users also use a virtualization solution product, such as VirtualBox and VMWare. VMs are in such a close distance to us.
Then, how can virtualization be made?
Hypervisor, the First Step to an Understanding of Virtualization
To understand VMs, you should learn about hypervisor, first. Basically, it is a program which controls and manages the operating system. Though the hypervisor method is the most used one among the virtualization technologies, it is not the only method for virtualization. This article will mainly focus on hypervisor but I will also explain other methods.
Figure 1: Classification of Virtualization Techniques.
A hypervisor is a piece of software that enables you to run one or more VMs on a physical server (host). In server virtualization, each VM is called a guest system (in some cases, guest OS), and a physical server on which such guest system runs is called a host system (in some cases, host OS).
Solutions such as Xen, VirtualBox, and VMWare are applicable to hypervisor. A hypervisor is divided into type 1 and type 2.
Type 1: A hypervisor runs on the host system without an OS (i.e., without a host OS).
Type 2: A host OS is installed on the host system and a hypervisor runs on it.
The hypervisor type that is familiar to general PC users is, of course, Type 2. VirtualBox and VMWare Workstation are all Type 2.
A VM solution does not require a host OS at all times. This is because their purpose is to provide VMs. This Type 1 includes Xen and VMWare ESX.
CPU Virtualization
The CPU installed on the host is only one set, but each VM that runs on the host requires their own CPU. This means the CPU itself also needs to be virtualized. Such CPU virtualization is made by a hypervisor. A hypervisor converts a set of CPU commands called by the OS of a VM (guest) and delivers it to the CPU and receives the result and delivers it.
There are several methods for converting and delivering a set of CPU commands. To better understand this, you need to first learn about privileged architecture, which is called the Hierarchical Protected Domains or Protection Ring of x86 server architecture. Figure 2 below shows this architecture:
Figure 2: x86 Privileged Architecture.
An OS that runs on x86 is designed on the assumption that it has all access/control authority for hardware. x86 architecture, as shown in Figure 2, uses four levels of Ring 0, 1, 2, and 3 to manage hardware access authority. While a user application is executed at Ring 3, an OS is performed at Ring 0 as it needs to directly access to memory or hardware.
This also applies to VMs themselves. VMs also require an OS (guest OS), and this OS requires Ring 0 authority. As this guest OS is unable to have Ring 0 authority directly, it should obtain Ring 0 authority by using a very complex method. This is the reason the complexity of x86 virtualization occurs. After all, the key to CPU virtualization is how privileged commands requested by the guest OS are processed at which level (i.e., by whom), and depending on it, CPU virtualization is divided into several methods, such as full virtualization and para virtualization, as shown in Figure 1 above.
Full Virtualization
In full virtualization, usually the hypervisor has Ring 0 authority and the guest OS has Ring 1 authority (see Figure 3 below):
Figure 3: Full Virtualization.
In full virtualization, machine language codes of the guest OS are converted into the machine language codes of the host through binary translation process. When a privileged command, such as device driver access, is required, a trap for device access event is executed on the hypervisor. Therefore, a variety of OS kinds, including MS Windows, can run on the hypervisor without any modification, but the speed is somewhat low due to the machine code conversion process.
To improve this, CPU manufacturers, including Intel (Intel VT) and AMD (AMD-V), provide a variety of functionalities to reduce virtualization overhead at the hardware level. A variety of technologies are being developed so that full virtualization can also provide as good performance as para virtualization (which is regarded to show better performance).
Figure 4: HW-assisted Virtualization.
A CPU that supports hardware-assisted virtualization additionally provides Ring-1 level (don't confuse with Ring 1), as shown in Figure 4 above, and the hypervisor runs on Ring-1 while the OS runs on Ring 0. Therefore, basically it does not require the process of binary translation for privileged commands, and a command is executed directly to hardware via the hypervisor, and this makes it much faster than the full virtualization method This has significantly reduced the performance gap between the full virtualization method and the para virtualization method (see Figure 5):
Figure 5L: 'Intel VT-x'-based Full Virtualization.
Para Virtualization
In the para virtualization method, when a privileged command is to be executed on the guest OS, it is delivered to the hypervisor by using a hypercall, a kind of system call, instead of OS, and the hypervisor receives this hypercall and accesses the hardware and returns the result (see Figure 6):
Figure 6: Xen's Para Virtualization.
As a guest OS is able to have the authority for direct control of resources, such as CPU and memory, the para virtualization method is relatively faster than the full virtualization method. However, it is a disadvantage that the OS kernel should be modified so that the VM OS can use a hypercall. Unlike full virtualization, therefore, para virtualization provides only a limited number of guest OSs the hypervisor can support (for Linux, approximately 20% of the entire kernel codes has been modified for para virtualization).
"Does Xen perform better than VMWare, as VMWare uses full virtualization and Xen uses para virtualization?"
I was personally asked of this question from some of my acquaintances. It's half right and half wrong. The early versions of VMWare employed full virtualization, but through a long-term commercialization process, it has been changed to support para virtualization as well. Currently, VMWare also runs many VM OSs in the para virtualization method (see Figure 7 below), and thus commercialized VMWare is now regarded to have little difference in functionality and performance, compared to Xen's hypervisor.
Figure 7: VMWare's Para Virtualization.
Host OS Virtualization
Host OS virtualization is a method in which an OS itself provides the hypervisor functionality (see Figure 8):
Figure 8: Host OS Virtualization.
This method could be thought of as an efficient method as virtualization environment is supported on the host OS. However, in fact, it is hardly used in server environments due to its weakness in inter-VM resource management, performance and security. For example, when a security issue occurs on the host OS where the hypervisor runs, the reliability of the entire guest OS can also have a problem. However, you can use it without any particular problem when you use it to use multiple OSs on your PC at the same time.
Container-based Virtualization
The container-based virtualization method is a method in which a Virtual Server Environment (VSE) is added to configure VM OS on the host OS instead of hypervisor and only the guest OS is emulated (see Figure 9).
Figure 9: Container-based Virtualization.
Whereas the virtualization technique by using the hypervisor method is the one for the entire hardware, the container-based method is only for the guest OS environment. For this reason, container-based virtualization is relatively light and shows good performance. However, this method is not much used in server environments because, like the host OS virtualization method, it has a weakness in inter-VM resource management and security management.
Memory Management
Of various memory management methods used on a guest OS, this article will explain the most used Shadow Page Table method.
Shadow Page Table
In general, an OS uses a page table to manage memory. Each process on an OS has a virtual memory address system (virtual address) it recognizes. A page table is used when matching the virtual memory address with a memory address system provided by a physical server (physical address). Frequently used address matching information is processed fast through hardware caches, and this is called Translation Lookup Buffer (TLB). Therefore, a guest OS also should have a page table, but the problem is that the guest OS can't access the memory address system of the host directly but only through the hypervisor. For this reason, a page table on the guest OS changes a virtual address on the OS into a physical address recognized by the guest OS. It is additionally required to match the memory address system of each VM provided by the hypervisor with the actual address system of the host (see Figure 10):
Figure 10: Configuration of Memory between Guest and Host.
A shadow page table is a technique used to reduce the overhead required for such virtual memory address translation. It allows you to avoid redundant virtual address translation by enabling you to translate a virtual memory address system on the guest OS directly into the address system of the host OS. For this, when any update occurs on the page table of the guest OS, the same update should be made on the shadow page table as well. The problem is that this task may make a significant negative influence on the guest OS performance. To address this problem, CPU manufacturers, such as Intel and AMD, provide functionalities to enhance memory-related performance at the hardware level, such as an Extended Page Table (EPT) (see Figure 11):
Figure 11: Intel EPT (Extended Page Table).
The methods provided by Intel and AMD have almost the same mechanism. Simply speaking, a kind of super TLB enables the virtual address of the guest OS to be translated directly into the physical address of the host.
Although TLB provides such information, TLB may be flushed if the guest OS itself is context-switched. To prevent this, a unique tag for each VM is provided to TLB, and through this, TLB flush can be prevented because it becomes recognizable to which guest each TLB entry belongs. As a result, this can provide a faster and more efficient memory management method.
Network Virtualization
When it comes to network virtualization, a variety of methods are provided for each hypervisor. The most common method is the one in which virtual switch is provided in the hypervisor and the network interface of the guest is connected with the NIC of the host (see Figure 12):
Figure 12: Network Virtualization.
The disadvantage of this method is that, when multiple guests run on the host and the network traffic is high, the virtual switch could be a bottleneck. To avoid this, you should use multiple NICs on the host and adjust the virtual switch connected to each NIC so that the network bandwidth used by the guest can be distributed.
However, this method is not perfect, either. It is not that efficient in some tasks, such as placing guests dynamically and moving a guest to another host by using live migration.
For a more ultimate solution, Intel provides the functionality of improving network performance by using some methods such as VT-c. The main VT-c technologies are: VMDq and SR-IOV.
VMDq (Virtual Machine Device Queue)
A hypervisor internally provides the virtual switch in software method. It provides the functionality of forwarding and switching packets sent from outside (see Figure 13 below). However, these methods do not provide fast network speed of guest systems.
To address this, Intel provides a method to boost the speed of packet classification by allowing the NIC level of the host to have a packet queue for each guest (see Figure 14).
Figure 13: When VMDq is not Used.
Figure 14: When VMDq is Used.
However, VMDq is supported by only some NICs of Intel.
SR-IOV (Single-Root IO Virtualization)
The concept of SR-IOV is as follows: it is a method in which the host PCI is virtualized as if multiple PCIs physically exist, and these virtual PCIs are directly allocated to each guest (see Figure 15 below). Strictly speaking, SR-IOV is not an independent technology of Intel. It is a technology, which is designed by Intel in a way to meet the standards provided by PCI-SIG (PCI -Special Interest Group) and is provided by our NIC. With SR-IOV, one physical I/O port is virtualized into multiple Virtual Functions (VFs), and each VF is allocated directly to the guest. In this case, the guest can exert I/O performance similar to when a physical PCI is directly allocated, and the deterioration of network performance due to virtualization is also significantly resolved.
Figure 15: SR-IOV.
However, SR-IOV is also supported only by some NICs of Intel.
Conclusion
Cloud solution developers' ultimate goal is to allow VM users to feel little difference in terms of functionality and performance, compared to when they use a physical server. One should understand, however, it is impossible to provide VMs that provide completely same functionality and performance as those of a physical server. As hypervisor and server hardware are making rapid progress at the moment, much more advanced VMs than the current ones will be provided in the future. As the genuine value of VMs is fast supply and cost reduction, which is way better than a physical server, using VMs for a variety of purposes is a way to enhance your development competitiveness and also help reduce costs.
By Soyoung Jeong, General Manager at Ncloud Development Team, NHN Corporation. [Less]
|
Posted
almost 12 years
ago
by
Soyoung Jeong
These days we can see virtualization technology everywhere in our daily life. In this article I will explain about the basic knowledge of virtualization, mainly with x86 architecture, the technology used for CPU, memory, and IO, as well as the trends
... [More]
of virtualization technology development.
Benefits of Server Virtualization
The universalization of virtual machines has brought many positive effects on computing environments and internet business. The most noticeable advantage of virtual machines is that they reduce server costs significantly. For example, many internet venture companies benefit from Amazon EC2. In addition to such cost merit, virtual machines also provide many benefits in terms of operation. They enable you to provide server infrastructure fast, and to control resources, such as memory size, remotely.
Since 2008, NHN has used virtual machines (VM) when a server is required for development/test purposes or, in some cases, to provide actual services. Ncloud Dev. Team at NHN released Ncloud, an integrated cloud solution service, in 2011, and has provided virtual servers both internally and externally.
The benefit of cloud solutions like Ncloud to developers is that it has universalized the application and use of servers. VMs enable you to get a server that you can use within a few minutes without any particular payment.
The field of servers is not the only place where such VMs are used. Many general users also use a virtualization solution product, such as VirtualBox and VMWare. VMs are in such a close distance to us.
Then, how can virtualization be made?
Hypervisor, the First Step to an Understanding of Virtualization
To understand VMs, you should learn about hypervisor, first. Basically, it is a program which controls and manages the operating system. Though the hypervisor method is the most used one among the virtualization technologies, it is not the only method for virtualization. This article will mainly focus on hypervisor but I will also explain other methods.
Figure 1: Classification of Virtualization Techniques.
A hypervisor is a piece of software that enables you to run one or more VMs on a physical server (host). In server virtualization, each VM is called a guest system (in some cases, guest OS), and a physical server on which such guest system runs is called a host system (in some cases, host OS).
Solutions such as Xen, VirtualBox, and VMWare are applicable to hypervisor. A hypervisor is divided into type 1 and type 2.
Type 1: A hypervisor runs on the host system without an OS (i.e., without a host OS).
Type 2: A host OS is installed on the host system and a hypervisor runs on it.
The hypervisor type that is familiar to general PC users is, of course, Type 2. VirtualBox and VMWare Workstation are all Type 2.
A VM solution does not require a host OS at all times. This is because their purpose is to provide VMs. This Type 1 includes Xen and VMWare ESX.
CPU Virtualization
The CPU installed on the host is only one set, but each VM that runs on the host requires their own CPU. This means the CPU itself also needs to be virtualized. Such CPU virtualization is made by a hypervisor. A hypervisor converts a set of CPU commands called by the OS of a VM (guest) and delivers it to the CPU and receives the result and delivers it.
There are several methods for converting and delivering a set of CPU commands. To better understand this, you need to first learn about privileged architecture, which is called the Hierarchical Protected Domains or Protection Ring of x86 server architecture. Figure 2 below shows this architecture:
Figure 2: x86 Privileged Architecture.
An OS that runs on x86 is designed on the assumption that it has all access/control authority for hardware. x86 architecture, as shown in Figure 2, uses four levels of Ring 0, 1, 2, and 3 to manage hardware access authority. While a user application is executed at Ring 3, an OS is performed at Ring 0 as it needs to directly access to memory or hardware.
This also applies to VMs themselves. VMs also require an OS (guest OS), and this OS requires Ring 0 authority. As this guest OS is unable to have Ring 0 authority directly, it should obtain Ring 0 authority by using a very complex method. This is the reason the complexity of x86 virtualization occurs. After all, the key to CPU virtualization is how privileged commands requested by the guest OS are processed at which level (i.e., by whom), and depending on it, CPU virtualization is divided into several methods, such as full virtualization and para virtualization, as shown in Figure 1 above.
Full Virtualization
In full virtualization, usually the hypervisor has Ring 0 authority and the guest OS has Ring 1 authority (see Figure 3 below):
Figure 3: Full Virtualization.
In full virtualization, machine language codes of the guest OS are converted into the machine language codes of the host through binary translation process. When a privileged command, such as device driver access, is required, a trap for device access event is executed on the hypervisor. Therefore, a variety of OS kinds, including MS Windows, can run on the hypervisor without any modification, but the speed is somewhat low due to the machine code conversion process.
To improve this, CPU manufacturers, including Intel (Intel VT) and AMD (AMD-V), provide a variety of functionalities to reduce virtualization overhead at the hardware level. A variety of technologies are being developed so that full virtualization can also provide as good performance as para virtualization (which is regarded to show better performance).
Figure 4: HW-assisted Virtualization.
A CPU that supports hardware-assisted virtualization additionally provides Ring-1 level (don't confuse with Ring 1), as shown in Figure 4 above, and the hypervisor runs on Ring-1 while the OS runs on Ring 0. Therefore, basically it does not require the process of binary translation for privileged commands, and a command is executed directly to hardware via the hypervisor, and this makes it much faster than the full virtualization method This has significantly reduced the performance gap between the full virtualization method and the para virtualization method (see Figure 5):
Figure 5L: 'Intel VT-x'-based Full Virtualization.
Para Virtualization
In the para virtualization method, when a privileged command is to be executed on the guest OS, it is delivered to the hypervisor by using a hypercall, a kind of system call, instead of OS, and the hypervisor receives this hypercall and accesses the hardware and returns the result (see Figure 6):
Figure 6: Xen's Para Virtualization.
As a guest OS is able to have the authority for direct control of resources, such as CPU and memory, the para virtualization method is relatively faster than the full virtualization method. However, it is a disadvantage that the OS kernel should be modified so that the VM OS can use a hypercall. Unlike full virtualization, therefore, para virtualization provides only a limited number of guest OSs the hypervisor can support (for Linux, approximately 20% of the entire kernel codes has been modified for para virtualization).
"Does Xen perform better than VMWare, as VMWare uses full virtualization and Xen uses para virtualization?"
I was personally asked of this question from some of my acquaintances. It's half right and half wrong. The early versions of VMWare employed full virtualization, but through a long-term commercialization process, it has been changed to support para virtualization as well. Currently, VMWare also runs many VM OSs in the para virtualization method (see Figure 7 below), and thus commercialized VMWare is now regarded to have little difference in functionality and performance, compared to Xen's hypervisor.
Figure 7: VMWare's Para Virtualization.
Host OS Virtualization
Host OS virtualization is a method in which an OS itself provides the hypervisor functionality (see Figure 8):
Figure 8: Host OS Virtualization.
This method could be thought of as an efficient method as virtualization environment is supported on the host OS. However, in fact, it is hardly used in server environments due to its weakness in inter-VM resource management, performance and security. For example, when a security issue occurs on the host OS where the hypervisor runs, the reliability of the entire guest OS can also have a problem. However, you can use it without any particular problem when you use it to use multiple OSs on your PC at the same time.
Container-based Virtualization
The container-based virtualization method is a method in which a Virtual Server Environment (VSE) is added to configure VM OS on the host OS instead of hypervisor and only the guest OS is emulated (see Figure 9).
Figure 9: Container-based Virtualization.
Whereas the virtualization technique by using the hypervisor method is the one for the entire hardware, the container-based method is only for the guest OS environment. For this reason, container-based virtualization is relatively light and shows good performance. However, this method is not much used in server environments because, like the host OS virtualization method, it has a weakness in inter-VM resource management and security management.
Memory Management
Of various memory management methods used on a guest OS, this article will explain the most used Shadow Page Table method.
Shadow Page Table
In general, an OS uses a page table to manage memory. Each process on an OS has a virtual memory address system (virtual address) it recognizes. A page table is used when matching the virtual memory address with a memory address system provided by a physical server (physical address). Frequently used address matching information is processed fast through hardware caches, and this is called Translation Lookup Buffer (TLB). Therefore, a guest OS also should have a page table, but the problem is that the guest OS can't access the memory address system of the host directly but only through the hypervisor. For this reason, a page table on the guest OS changes a virtual address on the OS into a physical address recognized by the guest OS. It is additionally required to match the memory address system of each VM provided by the hypervisor with the actual address system of the host (see Figure 10):
Figure 10: Configuration of Memory between Guest and Host.
A shadow page table is a technique used to reduce the overhead required for such virtual memory address translation. It allows you to avoid redundant virtual address translation by enabling you to translate a virtual memory address system on the guest OS directly into the address system of the host OS. For this, when any update occurs on the page table of the guest OS, the same update should be made on the shadow page table as well. The problem is that this task may make a significant negative influence on the guest OS performance. To address this problem, CPU manufacturers, such as Intel and AMD, provide functionalities to enhance memory-related performance at the hardware level, such as an Extended Page Table (EPT) (see Figure 11):
Figure 11: Intel EPT (Extended Page Table).
The methods provided by Intel and AMD have almost the same mechanism. Simply speaking, a kind of super TLB enables the virtual address of the guest OS to be translated directly into the physical address of the host.
Although TLB provides such information, TLB may be flushed if the guest OS itself is context-switched. To prevent this, a unique tag for each VM is provided to TLB, and through this, TLB flush can be prevented because it becomes recognizable to which guest each TLB entry belongs. As a result, this can provide a faster and more efficient memory management method.
Network Virtualization
When it comes to network virtualization, a variety of methods are provided for each hypervisor. The most common method is the one in which virtual switch is provided in the hypervisor and the network interface of the guest is connected with the NIC of the host (see Figure 12):
Figure 12: Network Virtualization.
The disadvantage of this method is that, when multiple guests run on the host and the network traffic is high, the virtual switch could be a bottleneck. To avoid this, you should use multiple NICs on the host and adjust the virtual switch connected to each NIC so that the network bandwidth used by the guest can be distributed.
However, this method is not perfect, either. It is not that efficient in some tasks, such as placing guests dynamically and moving a guest to another host by using live migration.
For a more ultimate solution, Intel provides the functionality of improving network performance by using some methods such as VT-c. The main VT-c technologies are: VMDq and SR-IOV.
VMDq (Virtual Machine Device Queue)
A hypervisor internally provides the virtual switch in software method. It provides the functionality of forwarding and switching packets sent from outside (see Figure 13 below). However, these methods do not provide fast network speed of guest systems.
To address this, Intel provides a method to boost the speed of packet classification by allowing the NIC level of the host to have a packet queue for each guest (see Figure 14).
Figure 13: When VMDq is not Used.
Figure 14: When VMDq is Used.
However, VMDq is supported by only some NICs of Intel.
SR-IOV (Single-Root IO Virtualization)
The concept of SR-IOV is as follows: it is a method in which the host PCI is virtualized as if multiple PCIs physically exist, and these virtual PCIs are directly allocated to each guest (see Figure 15 below). Strictly speaking, SR-IOV is not an independent technology of Intel. It is a technology, which is designed by Intel in a way to meet the standards provided by PCI-SIG (PCI -Special Interest Group) and is provided by our NIC. With SR-IOV, one physical I/O port is virtualized into multiple Virtual Functions (VFs), and each VF is allocated directly to the guest. In this case, the guest can exert I/O performance similar to when a physical PCI is directly allocated, and the deterioration of network performance due to virtualization is also significantly resolved.
Figure 15: SR-IOV.
However, SR-IOV is also supported only by some NICs of Intel.
Conclusion
Cloud solution developers' ultimate goal is to allow VM users to feel little difference in terms of functionality and performance, compared to when they use a physical server. One should understand, however, it is impossible to provide VMs that provide completely same functionality and performance as those of a physical server. As hypervisor and server hardware are making rapid progress at the moment, much more advanced VMs than the current ones will be provided in the future. As the genuine value of VMs is fast supply and cost reduction, which is way better than a physical server, using VMs for a variety of purposes is a way to enhance your development competitiveness and also help reduce costs.
By Soyoung Jeong, General Manager at Ncloud Development Team, NHN Corporation. [Less]
|
Posted
almost 12 years
ago
by
Hyehwan Ahn
NHN, the company behind CUBRID open source database development, is automating tests for diverse browsers (Chrome, Firefox, Internet Explorer, Opera, iOS Safari and Android) that run on a variety of operating systems (Linux, Microsoft Windows, Mac
... [More]
OS, iOS and Android) with a set of test codes by using Hudson and Selenium WebDriver. In this article, I will briefly summarize the test automation process we use at NHN's NAVER portal and the benefits of Hudson and Selenium WebDriver for automation.
How to Automate Tests
I registered a test code to Hudson, Continuous Integration (CI) tool, and set the test code to be executed by using Selenium WebDriver and JUnit whenever source is committed in SVN. It takes about 2 seconds to test a browser. When a problem occurs, the problem is reported within 10 minutes.
Hudson is commonly used in most development departments of NHN. By clicking Build Now, users can view the test progress status. The report system provides a good environment for "Fast Fail, Fast Feedback".
Figure 1: Multi-browser Test with One Set of Test Code.
Automating Firefox Test in Linux
Install xserver package on Linux server with Hudson. Modify run level to 5 and then add the following setting to an account where CI runs in order to execute a browser in a text console.
Xvfb :1 -screen 0 1024x768x24 > /home1/irteam/log/xvfb.log &
Install the latest Firefox version under the /usr/lib64 directory and replace the symbolic link. Now you can execute automation tests by running Firefox in Hudson.
Firefox Test Automation Demo Video (Youtube)
Automating iPhone and iPad Tests in Mac OS X and Simulator
For tests, install Hudson on Mac OS X. It requires the iPhone or iPad Simulator, so you should install Xcode in advance.
iPhone Test Automation Demo Video by Using Simulator (Youtube)
Automating Internet Explorer and Opera Tests in Microsoft Windows
For more details on how to automate tests in Microsoft Windows, see http://seleniumhq.org/docs/03_webdriver.html.
Why Is Browser Test Automation with Hudson Required?
If tests for several browsers are automatically executed whenever a source code is changed, it would clearly help developers to reduce bugs and keep the source tree that can be released anytime. In addition, QA time can be significantly reduced. There are many benefits of browser tests with Hudson, in addition to quality and cost. The following are the benefits of Hudson.
Keeping a Living Document and Building up Domain Knowledge
Whenever performing a test in Hudson, a document with illustration and description can be automatically generated by using Javadoc package.htm in the test code. This document is called a "living document" which is continuously updated and used by operators, developers and QAers for a variety of purposes such as hand-off of domain knowledge and preservation of revision history.
Figure 2: Javadoc Document Created from Tests.
Visualizing Service Quality by Browser and Domain Knowledge
Anyone who clicks Build Now in Hudson can check the service quality by browser.
Figure 3: Verifying Mobile News Service in Firefox.
For example, in some cases, the news service should be provided differently by day due to the service characteristics. It is very difficult to hand off all domain information to all related staffs. For example, the KOSPI/KOSDAQ indexes are not showed on the news on weekends but after the opening of the market on Monday morning. Anyone who clicks the Build Now button can see the news service operation process by status.
Tests with Hudson help users to hand off domain knowledge and build up the information as well as enhance quality and cut costs.
Best Practices and Examples
We once needed to update the version of Spring Framework used for the mobile news service. We modified the version information in the pom.xml file of Maven and performed the unit test and the integration test for web server source, and the result was no problem. Developers opened some new web pages by running the web server and checked that all of them were fine.
However, there were more than 80 runtime errors. Fortunately, we had the multi-browser test in Hudson test, so we could fix all bugs and problems before releasing the service.
Selenium WebDriver
Why Selenium WebDriver?
We use Selenium WebDriver because of its reliable quality through a version up process for a long time, and it is easy-to-use. The test is performed by running a browser, so it is easy to perform UI test by browser.
The virtual browser test such as HtmlUnit cannot support a variety of browser versions (it is limited to Firefox 3.6 and lower and Internet Explorer 8 and lower). In addition, it does not support mobile browsers. Therefore, I recommend Selenium WebDriver over HtmlUnit, even though Selenium WebDriver requires more effort.
With Java API provided by Selenium WebDriver at the JUnit test code, you can easily produce the browser test code. Code 1 below is now used for the mobile news service test.
Code 1. News Service Test Code.
@Test(timeout = 1000 * 60) public void 뉴스홈에_최근3일_최종편집시간이_표시된다() { Driver.get(driver, "http://m.news.naver.com/home.nhn"); String expectedResult = "최종편집"; String result = Driver.getTextByClass(driver, "last_update"); assertThat(result.startsWith(expectedResult), is(true)); }
Benefits of Selenium WebDriver
Benefits of Selenium WebDriver are various: it allows developers to produce the test code with a variety of languages (Java, C#, Python, PHP, Ruby, Perl) and provides fast feedback by using the implicit wait function. The following are the benefits of Selenium WebDriver.
Test by Specifying ID/Class/XPath
If considering HTML maintenance, ID is the best choice to specify HTML/CSS elements, the second best is Class, and finally, XPath. Selenium WebDriver supports all three.
Multi-browser Tests with One Set of Test Code
You can test several browsers with one set of test code because you can change the test browser by replacing WebDriver only. As of 2012, WebDriver supports Firefox, Internet Explorer, Chrome, Opera, iPhone Safari, iPad Safari and Android browsers. Code 2 below is a part of code that creates WebDriver.
Code 2. Example of Creating WebDriver.
public WebDriverFactory() throws Exception { String browsetype = TestConfigParam.getBrowseType(); if ("firefox".equals(browsetype)) { this.driver = new FirefoxDriver(); } else if ("chrome".equals(browsetype)) { this.driver = new ChromeDriver(); } else if ("ie".equals(browsetype)) { this.driver = new InternetExplorerDriver(); } else if ("iphone".equals(browsetype)) { this.driver = new IPhoneDriver(); } else if ("ie".equals(browsetype)) { this.driver = new InternetExplorerDriver(); } else if ("android".equals(browsetype)) { this.driver = new AndroidDriver(); } else if ("htmlunit".equals(browsetype)) { this.driver = new HtmlUnitDriver(false); } else { this.driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Driver.TIMEOUT, TimeUnit.SECONDS); } }
Conclusion
So far, we have reviewed test automation applied to NAVER services. NHN has already automated tests for many services by using Hudson and Selenium WebDriver. I guess other companies have automated tests in the similar ways. Therefore, I hope this article to be a chance to communicate with others to create a Best Practice, rather than showing it for test methods.
By Hyehwan Ahn, Software Engineer at News Service Development Team, NHN Corporation.
I am a developer who is interested in automation of routine tasks in releasing Alpha/Beta/QA/Distribution phases to improve efficiency.
[Less]
|
Posted
almost 12 years
ago
by
Hyehwan Ahn
NHN, the company behind CUBRID open source database development, is automating tests for diverse browsers (Chrome, Firefox, Internet Explorer, Opera, iOS Safari and Android) that run on a variety of operating systems (Linux, Microsoft Windows, Mac
... [More]
OS, iOS and Android) with a set of test codes by using Hudson and Selenium WebDriver. In this article, I will briefly summarize the test automation process we use at NHN's NAVER portal and the benefits of Hudson and Selenium WebDriver for automation.
How to Automate Tests
I registered a test code to Hudson, Continuous Integration (CI) tool, and set the test code to be executed by using Selenium WebDriver and JUnit whenever source is committed in SVN. It takes about 2 seconds to test a browser. When a problem occurs, the problem is reported within 10 minutes.
Hudson is commonly used in most development departments of NHN. By clicking Build Now, users can view the test progress status. The report system provides a good environment for "Fast Fail, Fast Feedback".
Figure 1: Multi-browser Test with One Set of Test Code.
Automating Firefox Test in Linux
Install xserver package on Linux server with Hudson. Modify run level to 5 and then add the following setting to an account where CI runs in order to execute a browser in a text console.
Xvfb :1 -screen 0 1024x768x24 > /home1/irteam/log/xvfb.log &
Install the latest Firefox version under the /usr/lib64 directory and replace the symbolic link. Now you can execute automation tests by running Firefox in Hudson.
Firefox Test Automation Demo Video (Youtube)
Automating iPhone and iPad Tests in Mac OS X and Simulator
For tests, install Hudson on Mac OS X. It requires the iPhone or iPad Simulator, so you should install Xcode in advance.
iPhone Test Automation Demo Video by Using Simulator (Youtube)
Automating Internet Explorer and Opera Tests in Microsoft Windows
For more details on how to automate tests in Microsoft Windows, see http://seleniumhq.org/docs/03_webdriver.html.
Why Is Browser Test Automation with Hudson Required?
If tests for several browsers are automatically executed whenever a source code is changed, it would clearly help developers to reduce bugs and keep the source tree that can be released anytime. In addition, QA time can be significantly reduced. There are many benefits of browser tests with Hudson, in addition to quality and cost. The following are the benefits of Hudson.
Keeping a Living Document and Building up Domain Knowledge
Whenever performing a test in Hudson, a document with illustration and description can be automatically generated by using Javadoc package.htm in the test code. This document is called a "living document" which is continuously updated and used by operators, developers and QAers for a variety of purposes such as hand-off of domain knowledge and preservation of revision history.
Figure 2: Javadoc Document Created from Tests.
Visualizing Service Quality by Browser and Domain Knowledge
Anyone who clicks Build Now in Hudson can check the service quality by browser.
Figure 3: Verifying Mobile News Service in Firefox.
For example, in some cases, the news service should be provided differently by day due to the service characteristics. It is very difficult to hand off all domain information to all related staffs. For example, the KOSPI/KOSDAQ indexes are not showed on the news on weekends but after the opening of the market on Monday morning. Anyone who clicks the Build Now button can see the news service operation process by status.
Tests with Hudson help users to hand off domain knowledge and build up the information as well as enhance quality and cut costs.
Best Practices and Examples
We once needed to update the version of Spring Framework used for the mobile news service. We modified the version information in the pom.xml file of Maven and performed the unit test and the integration test for web server source, and the result was no problem. Developers opened some new web pages by running the web server and checked that all of them were fine.
However, there were more than 80 runtime errors. Fortunately, we had the multi-browser test in Hudson test, so we could fix all bugs and problems before releasing the service.
Selenium WebDriver
Why Selenium WebDriver?
We use Selenium WebDriver because of its reliable quality through a version up process for a long time, and it is easy-to-use. The test is performed by running a browser, so it is easy to perform UI test by browser.
The virtual browser test such as HtmlUnit cannot support a variety of browser versions (it is limited to Firefox 3.6 and lower and Internet Explorer 8 and lower). In addition, it does not support mobile browsers. Therefore, I recommend Selenium WebDriver over HtmlUnit, even though Selenium WebDriver requires more effort.
With Java API provided by Selenium WebDriver at the JUnit test code, you can easily produce the browser test code. Code 1 below is now used for the mobile news service test.
Code 1. News Service Test Code.
@Test(timeout = 1000 * 60) public void 뉴스홈에_최근3일_최종편집시간이_표시된다() { Driver.get(driver, "http://m.news.naver.com/home.nhn"); String expectedResult = "최종편집"; String result = Driver.getTextByClass(driver, "last_update"); assertThat(result.startsWith(expectedResult), is(true)); }
Benefits of Selenium WebDriver
Benefits of Selenium WebDriver are various: it allows developers to produce the test code with a variety of languages (Java, C#, Python, PHP, Ruby, Perl) and provides fast feedback by using the implicit wait function. The following are the benefits of Selenium WebDriver.
Test by Specifying ID/Class/XPath
If considering HTML maintenance, ID is the best choice to specify HTML/CSS elements, the second best is Class, and finally, XPath. Selenium WebDriver supports all three.
Multi-browser Tests with One Set of Test Code
You can test several browsers with one set of test code because you can change the test browser by replacing WebDriver only. As of 2012, WebDriver supports Firefox, Internet Explorer, Chrome, Opera, iPhone Safari, iPad Safari and Android browsers. Code 2 below is a part of code that creates WebDriver.
Code 2. Example of Creating WebDriver.
public WebDriverFactory() throws Exception { String browsetype = TestConfigParam.getBrowseType(); if ("firefox".equals(browsetype)) { this.driver = new FirefoxDriver(); } else if ("chrome".equals(browsetype)) { this.driver = new ChromeDriver(); } else if ("ie".equals(browsetype)) { this.driver = new InternetExplorerDriver(); } else if ("iphone".equals(browsetype)) { this.driver = new IPhoneDriver(); } else if ("ie".equals(browsetype)) { this.driver = new InternetExplorerDriver(); } else if ("android".equals(browsetype)) { this.driver = new AndroidDriver(); } else if ("htmlunit".equals(browsetype)) { this.driver = new HtmlUnitDriver(false); } else { this.driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Driver.TIMEOUT, TimeUnit.SECONDS); } }
Conclusion
So far, we have reviewed test automation applied to NAVER services. NHN has already automated tests for many services by using Hudson and Selenium WebDriver. I guess other companies have automated tests in the similar ways. Therefore, I hope this article to be a chance to communicate with others to create a Best Practice, rather than showing it for test methods.
By Hyehwan Ahn, Software Engineer at News Service Development Team, NHN Corporation.
I am a developer who is interested in automation of routine tasks in releasing Alpha/Beta/QA/Distribution phases to improve efficiency.
[Less]
|
Posted
almost 12 years
ago
by
Lukas Eder
This is a guest post by Lukas Eder, the creator of jOOQ open source Java API for typesafe SQL modeling. If you develop or use an open source application and would like to tell the world about it, CUBRID open source database project is accepting guest
... [More]
posts.
Big Data, the Web and SQL
In recent years, software companies have started to raise millions up to billions of dollars getting acquired by a big player, such as Google, Facebook, Yahoo! or Microsoft. Very often, the assumed value of such deals lay in the fact that Big Data could be purchased along with such acquisitions. "Social" Big Data was generated by millions of users over the web. It seemed too big to fit in classic relational databases, which is why the purchases also included buying the proprietary, rather short-lived technologies used to maintain Big Data. Most of the new companies thus experimented with NoSQL in one form or another.
SQL, on the other hand, has come a long way. SQL is a very expressive and powerful language used to model queries against any type of data, albeit mostly relational. At the same time, SQL is standardised and quite open. CUBRID is a good example of an object-relational database, which combines the expressiveness of SQL with high availability, sharding, and many other features needed to manage Big Data! In other words, CUBRID is the proof that SQL can be an adequate technology for the modern web.
Querying CUBRID with jOOQ
jOOQ is a Java API modelling SQL as an internal domain-specific language directly in Java. It features a built-in code generator to generate Java classes from your database model. These generated classes can then be used to create typesafe SQL queries directly in Java. A simple example of how this works with CUBRID can be seen in this jOOQ CUBRID tutorial.
The idea of creating fluent APIs in Java is not new. Usually, Martin Fowler takes most credits for his elaborations on the subject. After that, many approaches towards building internal domain-specific languages have surfaced, mostly in unit testing environments (e.g. JMock and Mockito). Apart from jOOQ, there are also a couple of fluent APIs that model SQL as a language in Java. These include:
JaQu
OneWebSQL
Quaere
QueryDSL
Squill
Among the above, QueryDSL is the only other API with a comparable traction to jOOQ's. While QueryDSL hides the full SQL expressiveness behind a LINQesque API, jOOQ strongly focuses on SQL only. Unlike any of the above SQL abstraction APIs, jOOQ combines these features:
A BNF defines jOOQ's fluent API
jOOQ uses next generation techniques to implement its fluent API. These techniques involve a formal BNF notation specifying API type and method hierarchies:
With a formal BNF, jOOQ's fluent API is much more robust and typesafe, as it will dictate syntax correctness in a more formal way than ordinary builder APIs.
jOOQ embraces usage of stored procedures
When closely coupling with your favourite relational database, you will likely want to make use of stored procedures and functions, directly in your SQL. jOOQ embraces this fact and allows for typesafe embedding of stored functions.
jOOQ embraces usage of row value expressions
Row value expressions (also called tuples, records) are at the heart of SQL. Few libraries outside of the SQL world will be able to model the fact that the following predicates are type-safe:
SELECT * FROM t1 WHERE t1.a = (SELECT t2.a FROM t2) -- Types must match: ^^^^ ^^^^ SELECT * FROM t1 WHERE (t1.a, t1.b) IN (SELECT t2.a, t2.b FROM t2) -- Types must match: ^^^^^^^^^^^^ ^^^^^^^^^^ SELECT t1.a, t1.b FROM t1 UNION SELECT t2.a, t2.b FROM t2 -- ^^^^^^^^^^ Types must match ^^^^^^^^^^
jOOQ will leverage the Java compiler to help you check the above:
select().from(t1).where(t1.a.eq(select(t2.a).from(t2)); // Type-check here: -----------------> ^^^^ select().from(t1).where(row(t1.a, t1.b).in(select(t2.a, t2.b).from(t2))); // Type-check here: ----------------------------> ^^^^^^^^^^ select(t1.a, t1.b).from(t1).union(select(t2.a, t2.b).from(t2)); // Type-check here: -------------------> ^^^^^^^^^^
jOOQ emulates built-in functions and SQL clauses
Providing support for simple SQL clauses is easy: SELECT, DISTINCT, FROM, JOIN, GROUP BY, etc. Implementing "real" SQL is much harder, though. Take the above row value expressions, for instance. They are currently not supported in CUBRID, but you can use them nonetheless with jOOQ. jOOQ emulates missing functions and SQL clauses for you as can be seen in this syndicated blog post.
jOOQ renders specialised SQL for 14 major RDBMS vendors
Instead of generalising and abstracting advanced standard and vendor-specific SQL features, such as JPA and tools built upon JPA, jOOQ sees good things in each vendor-specific syntax element. You know your database well, so you want to leverage it, not abstract it.
jOOQ is a platform
jOOQ is much more than just a SQL library. For example, it features the very useful jOOQ Console, which helps you debug and profile your jOOQ-generated SQL statements in any environment, without the need for expensive third-party tools:
The jOOQ Console also includes on-the-fly SQL editing tools as well as breakpoint capability for advanced debugging.
More feature comparisons
More feature comparisons can be found here, in this blog post.
Getting productive with jOOQ
jOOQ is a vision where SQL matters again to the Java developer. While some have called ORM to be the Vietnam of Computer Science, jOOQ is the Peace Treaty Between SQL and Java. Using the above and many more features, you can be productive again when writing high-performing, specialised SQL against your favourite database directly in Java, typesafely compiled by your Java compiler.
By Lukas Eder, the creator of jOOQ. Follow him on Twitter @JavaOOQ.
I'm a Java and SQL enthusiast developer currently contracting for Adobe Systems in Basel, Switzerland. Originating from the E-Banking field, I have a strong Oracle SQL background. I'm the creator of jOOQ, a comprehensive SQL library for Java.
[Less]
|
Posted
almost 12 years
ago
by
Phil Jackson
This is a guest post by Phil Jackson, the creator of ApiAxle open source API management and analytics solution. If you develop or use an open source application and would like to tell the world about it, CUBRID open source database project is
... [More]
accepting guest posts.
ApiAxle is an API management solution which is open source and free. The basic premise is that you build your API, put ApiAxle in front of it and it will handle user authentication, rate limiting, statistics, etc. I represent a business which generates a revenue through support and consultancy, but first and foremost I am a developer who loves APIs and the idea of companies exposing their data to enable people to build some brilliant things. As a company we are enjoying building a great product and watching it gain traction amongst fellow hackers.
The API problem
We noticed a space in the market for an open source, on-premise proxy which did not cost the earth and did not involve sending your data over multiple, high-latency hops out into the cloud.
Where a developer these days can type apt-get install nginx to get a solid webserver, there was not really an equivalent for an API management system. Building out the features we provide can be a time-consuming, monotonous and error-prone process that we really hope people do not keep having to perform.
The solution
That is where we come in. We want to bury our head in security documentation and RFCs so that you can concentrate on making a great API. With a few simple commands you can be up and running within 20 minutes. Within 30 you can be on-boarding customers, authenticating them and getting detailed statistics about their usage. You will also get caching, rate limiting, HTTPS support and a highly configurable logging system.
How it works
There are three components in ApiAxle:
The REPL
You probably want this first. The repl allows you to configure ApiAxle from the command line. Setting up an API and API keys ready for the proxy to work with is easy. It fires up an instance of ApiAxle’s own HTTP API in the background and uses that to modify aspects of the system. Anything you can do in the REPL you can do programmatically with the API too.
Install:
$ sudo npm install apiaxle-repl
Start:
$ apiaxle
Configure an API and a new key to use the API with:
axle> key "05050c14643dc" create axle> api "acme" create endPoint="localhost:81" axle> api "acme" linkkey "05050c14643dc"
The Proxy
The kernel of the system. This goes between the Internet and your API and does the authentication, throttling, caching and statistics collection. It’is fast, secure and easy to setup. You will need either the REPL or the API to configure it first.
It does not matter what your API actually outputs - ApiAxle never modifies the body of a response. With regards to errors (e.g. user over quota) you can tell ApiAxle what format they should be in. We support XML or JSON. If you have Node.js installed, installation is as simple as:
$ sudo npm install apiaxle-proxy
Then start the proxy with:
$ apiaxle-proxy
The API
Bear with me, this gets a bit meta. This is ApiAxle’s own HTTP API which gives you full control over your APIs and the API keys and keyrings used to access them. You can view statistics about individual APIs and API keys from week long granularities right down to near-real-time hits at a single second granularity.
Install:
$ sudo npm install apiaxle-api
Start:
$ apiaxle-api
Find out which APIs you have configured:
$ curl "localhost:3000/v1/apis"
Where we are headed to
We have lots planned, to summarise:
Client drivers for the API. Demand is high for PHP and Ruby so we will get them done ASAP.
Now that OAuth2 has been ratified we will be working on getting that in as an authentication method.
We are working on a dashboard which will give you a way to manage your APIs, keys, keyrings and give you a way to view real-time and historical statistics - this will be a paid-for service.
We will be pushing out a user registration system soon so that you can on-board and bill customers without any manual intervention.
So the future is exciting. We are really looking forward to meeting more developers that are interested in APIs and the huge ecosystem that is formed around them. Please feel free to get in touch with any questions or just to say hi!
By Phil Jackson, the creator of ApiAxle. Follow him on Twitter @philjackson.
After receiving his computing degree from Teesside University, Phil became a software engineer. As he moved through industry, he found himself becoming increasingly fascinated with APIs and, after helping the BBC write their iPlayer API, founded Qwerly, a company that aggregated social profile information and offered it to companies for insight/marketing purposes. After selling Qwerly to a competitor, taking some time off, Phil wrote the code which would eventually make up ApiAxle. Now he's running ApiAxle full-time and hopes it will become the ubiquitous, open source tool for managing APIs.
[Less]
|
Posted
almost 12 years
ago
by
Esen Sagynov
At CUBRID we know how much important and difficult at the same time it is to find the right audience who would listen to what your open source project has to offer. Due to its nature, most OS projects, especially those driven by a community of
... [More]
likeminded enthusiasts, often do not possess the budget to reach out to target users. If you are a member of such community and would like to tell the world about it, read on. We have good news for you!
Last year we announced the CUBRID Affiliates Program through which we have already donated 3000 USD to 14 open source projects. Some of these projects provide very useful features to CUBRID Database users. This time we want to periodically introduce to our CUBRID community members one or two handpicked open source projects that we think are also potential and worth talking about. Starting from today we will accept guest posts to our CUBRID Blog from open source communities where they can introduce their software to our readers. We will handle the promotion.
Step 1: Pitch it!
We are looking for great software that will make our and our readers' eyes sparkle. Before your post gets published, we would like to read an overview of your project. Send us a brief email introducing your project: site links, introductory videos, presentations if available, what it does, what benefits it can provide to our readers. We will get back to you in no time.
Step 2: Write it!
If we accept your pitch, we will ask you to write a full post that should cover your software. You can include images and even video. In your introduction you need to tell the readers what problem your software solves, where and how a reader can take off, and, very importantly, how it differs from other existing solutions (I am sure there is at least one product you can compare with). Together with your article, send us your bio and Gravatar enabled email address.
Step 3: Get published!
We will create an account for you on our CUBRID community site and associate your email address it with. Then we will publish your post under your name so that you can receive notifications for comments as the post author. Once published, we will share your story on CUBRID Facebook, Twitter, Google+ pages as well as other networking sites like the popular DZone. On top of that we will place a 223x170 pixel banner on the top right of CUBRID Blog site, if you provide one, as well as pay at least $5 (about 11K impressions) to promote your post on Facebook timeline.
Like it? Then go on and contact us! [Less]
|
Posted
almost 12 years
ago
by
Jaehong Kim
Last month a colleague of mine has already covered Vert.x, a relatively new Java application framework which provides noticable performance advantage over competing technologies and features multi programming language support. The previous article
... [More]
has explained us about the philosophy of Vert.x, performance comparison with Node.js, internal structure of Vert.x, and many more. Today, I would like to continue this conversation and talk more about Vert.x architecture.
Considerations Used to Develop Vert.x
Polyglot is the feature making Vert.x stand out from other server frameworks. In the past, server frameworks could not support multiple languages. Supporting several languages does more than expand the range of users. More important thing is that services using different languages in a distributed environment can intercommunicate with ease. Of course, supporting a variety of languages is not sufficient for supporting a distributed environment. Essential functions of greater priority for a distributed environment include address system or message bus. Vert.x framework provides these functions. As Vert.x provides these functions as well as Polyglot, the benefits of Vert.x should be considered for a distributed environment.
As Vert.x supports a universal server framework, a variety of workloads should be considered. We should consider unusal cases different from Nginx, which is typically used as a Web server, or Node.js. It is to build a universal server application that processes a variety of protocols except HTTP (i.e., not a Web server which executes simple operations, considering scalability in a 3-tier environment). In order to accomplish this, Vert.x provides an additional thread pool while using the Run Loop method.
We will discuss Vert.x architecture starting from the thread pool and a consideration for a distributed environment.
Run Loop and Thread Pool
Vert.x and asynchronous server applications (or frameworks), include Ngin.x and Node.js, use the Run Loop method. Vert.x uses the term 'Event Loop' instead of 'Run Loop'. However, as Run Loop is the more popular term among some developers. I use this term, Run Loop, here. Run Loop, as you will guess from the name, is a method for checking whether there is a new event in the infinite loop, and calling an event handler when an event has been received. As such, the asynchronous server application and the event-based server application are different terms indicating an identical target, similar to ‘enharmonic' for music. To use the Run Loop method, all I/Os should be managed as events.
For example, imagine a general Web server application that creates a query for a database to respond to an HTTP request from a Web browser. The CPU of the Web server is used when one thread analyzes the HTTP request to execute proper business logic, and creates a query statement. However, the CPU is not used while the thread sends the query to the database and waits for a response. However, when the thread to be created equals the number of HTTP requests (Thread per Connection), another thread may be processing a task requiring the web server CPU, while one thread is waiting for response from the database. Finally, the web server CPU is used to process HTTP requests. As you know, the weakness of Thread per Connection is the cost for context switching at the kernel level since many threads must be created. This can be called waste.
The asynchronous event handling method can overcome this weakness (figuratively speaking, 'asynchronous event handling' is the 'purpose' and ‘Run Loop’ is the 'means'). If ‘HTTP request itself’ and ‘receiving a response from the database’ are created as an event, and the Run Loop calls the corresponding event handler whenever an event is received, the execution performance of the application can be enhanced by avoiding unnecessary context switching. In this fashion, to utilize a CPU efficiently, the number of Run Loops required equals the number of cores (i.e., thread should be created equaling the number of cores and each thread should run the Run Loop).
However, there is another problem creating threads equaling the number of cores, which is preventing as much context switching as possible. If a handler, using server resources, takes a long time to handle an event, other events received while the handler is being executed are not managed in a timely manner. A popular example is file searching on the server disk. In this case, it is better to create a separate thread for searching files.
Therefore, to build a universal server framework with asynchronous event handling, the framework should have a function for managing a thread pool. This is the aim of Vert.x. Thread pool management is the biggest difference between Vert.x and Node.js, except for polyglot. Vert.x creates Run Loops (Event Loops) equaling the number of cores and provides thread pool-related function to handle tasks using server resources requiring long periods for event handling.
Why is Hazelcast Used?
Vert.x uses Hazelcast, an In-Memory Data Grid (IMDG). Hazelcast API is not directly revealed to users but is used in Vert.x. When Vert.x is started, Hazelcast is started as an embedded element.
Hazelcast is a type of distributed storage. When storage is embedded and used in a server framework, we can obtain expected effects from a distributed environment.
The most popular case is session data processing. Vert.x calls it Shared Data. It allows multiple Vert.x instances to share the same data. Of course, additional RDBMS, instead of Hazelcast, will bring the same effect from the functional side. It is natural that embedded memory storage can consistently provide results faster than remote RDBMS. Therefore, users who need sessions for e-commerce or chatting servers can build a system with a simple configuration by using only Vert.x.
Hazelcast allows a message queue use without additional costs or investments (without server costs or monitoring of message queue instances). As mentioned before, Hazelcast is a distributed storage. It can duplicate a storage for reliability. By using this distributed storage as a queue, the server application implemented by using Vert.x becomes a message processing server application and a distributed queue.
These benefits make Vert.x a strong framework in a distributed environment.
Understanding Vert.x Components
Figure 1: Vert.x Architecture (Component) Diagram.
Figure 1 above shows a diagram of Vert.x components. As shown in the figure, in all Vert.x instances (these can be understood as a JVM), a Hazelcast is embedded and runs. The embedded Hazelcast is connected to Hazelcast in other Vert.x instances. Event Bus uses functions of Hazelcast. Hazelcast itself provides a certain level of reliability (because of WAL records and data duplication). So, events can be forwarded with a certain level of reliability.
HTTP Server and Net Server
HTTP Server and Net Server control network events and event handlers. A Net Server is for events and handlers private protocol, and an HTTP Server allows registering a handler to an HTTP event such as GET or POST. The reason for preparing an HTTP Server is eliminating the need to add event types, as well as the universality of HTTP itself. HTTP Server supports WebSocket as well as HTTP.
Figure 2: Event and Handler of HTTP Server.
Vert.x Thread Pool
Vert.x has three types of thread pools:
Acceptor: A thread to accept a socket. One thread is created for one port.
Event Loops: (same with Run Loop) equals the number of cores. When an event occurs, it executes a corresponding handler. When execution is performed, it repeats reading another event.
Background: Used when Event Loop executes a handler and an additional thread is required. Users can specify the number of threads in vertx.backgroundPoolSize, an environmental variable. The default is 20. Using too many threads causes an increase in context switching costs, so be cautious.
Event Loops can be described as follows in a detailed way. Event Loops use Netty NioWorkder as it is. All handlers specified by verticles run on Event Loops. Each verticle instance has its specified NioWorker. As such, it is guaranteed that a verticle instance is always executed on an identical thread. Therefore, verticles can be written in a thread-safe manner.
Conclusion
So far, I have briefly described Vert.x architecture. Since Vert.x framework is not widely used, I believe it would be better to detail the concept of designing Vert.x than detail each Vert.x component. Even if you have no interest in network server frameworks, it is helpful to review new products and determine differences between new and existing products. Doing so helps in understanding the evolution and direction of software products that are flooding today's market.
By Jaehong Kim, Senior Engineer at Web Platform Development Lab, NHN Corporation. [Less]
|