DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Latest Articles - DZone

article thumbnail
Rx-java subscribeOn and observeOn
If you have been confused by Rx-java ObservablesubscribeOn and observeOn, one of the blog articles that helped me understand these operations is this one by Graham Lea. I wanted to recreate a very small part of the article here, so consider a service which emits values every 200 millseconds: package obs.threads; import obs.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import rx.Observable; public class GeneralService { private static final Logger logger = LoggerFactory.getLogger(GeneralService.class); public Observable getData() { return Observable.create(s -> { logger.info("Start: Executing a Service"); for (int i = 1; i <= 3; i++) { Util.delay(200); logger.info("Emitting {}", "root " + i); s.onNext("root " + i); } logger.info("End: Executing a Service"); s.onCompleted(); }); } } Now, if I were to subscribe to this service, this way: @Test public void testThreadedObservable1() throws Exception { Observable ob1 = aService.getData(); CountDownLatch latch = new CountDownLatch(1); ob1.subscribe(s -> { Util.delay(500); logger.info("Got {}", s); }, e -> logger.error(e.getMessage(), e), () -> latch.countDown()); latch.await(); } All of the emissions and subscriptions will act on the main thread and something along the following lines will be printed: 20:53:29.380 [main] INFO o.t.GeneralService - Start: Executing a Service 20:53:29.587 [main] INFO o.t.GeneralService - Emitting root 1 20:53:30.093 [main] INFO o.t.ThreadedObsTest - Got root 1 20:53:30.298 [main] INFO o.t.GeneralService - Emitting root 2 20:53:30.800 [main] INFO o.t.ThreadedObsTest - Got root 2 20:53:31.002 [main] INFO o.t.GeneralService - Emitting root 3 20:53:31.507 [main] INFO o.t.ThreadedObsTest - Got root 3 20:53:31.507 [main] INFO o.t.GeneralService - End: Executing a Service By default the emissions are not asynchronous in nature. So now, what is the behavior if subscribeOn is used: public class ThreadedObsTest { private GeneralService aService = new GeneralService(); private static final Logger logger = LoggerFactory.getLogger(ThreadedObsTest.class); private ExecutorService executor1 = Executors.newFixedThreadPool(5, new ThreadFactoryBuilder().setNameFormat("SubscribeOn-%d").build()); @Test public void testSubscribeOn() throws Exception { Observable ob1 = aService.getData(); CountDownLatch latch = new CountDownLatch(1); ob1.subscribeOn(Schedulers.from(executor1)).subscribe(s -> { Util.delay(500); logger.info("Got {}", s); }, e -> logger.error(e.getMessage(), e), () -> latch.countDown()); latch.await(); } } Here I am using Guava's ThreadFactoryBuilder to give each thread in the threadpool a unique name pattern, if I were to execute this code, the output will be along these lines: 20:56:47.117 [SubscribeOn-0] INFO o.t.GeneralService - Start: Executing a Service 20:56:47.322 [SubscribeOn-0] INFO o.t.GeneralService - Emitting root 1 20:56:47.828 [SubscribeOn-0] INFO o.t.ThreadedObsTest - Got root 1 20:56:48.032 [SubscribeOn-0] INFO o.t.GeneralService - Emitting root 2 20:56:48.535 [SubscribeOn-0] INFO o.t.ThreadedObsTest - Got root 2 20:56:48.740 [SubscribeOn-0] INFO o.t.GeneralService - Emitting root 3 20:56:49.245 [SubscribeOn-0] INFO o.t.ThreadedObsTest - Got root 3 20:56:49.245 [SubscribeOn-0] INFO o.t.GeneralService - End: Executing a Service Now, the execution has moved away from the main thread and the emissions and the subscriptions are being processed in the threads borrowed from the threadpool. And what happens if observeOn is used: public class ThreadedObsTest { private GeneralService aService = new GeneralService(); private static final Logger logger = LoggerFactory.getLogger(ThreadedObsTest.class); private ExecutorService executor1 = Executors.newFixedThreadPool(5, new ThreadFactoryBuilder().setNameFormat("SubscribeOn-%d").build()); @Test public void testObserveOn() throws Exception { Observable ob1 = aService.getData(); CountDownLatch latch = new CountDownLatch(1); ob1.observeOn(Schedulers.from(executor2)).subscribe(s -> { Util.delay(500); logger.info("Got {}", s); }, e -> logger.error(e.getMessage(), e), () -> latch.countDown()); latch.await(); } } the output is along these lines: 21:03:08.655 [main] INFO o.t.GeneralService - Start: Executing a Service 21:03:08.860 [main] INFO o.t.GeneralService - Emitting root 1 21:03:09.067 [main] INFO o.t.GeneralService - Emitting root 2 21:03:09.268 [main] INFO o.t.GeneralService - Emitting root 3 21:03:09.269 [main] INFO o.t.GeneralService - End: Executing a Service 21:03:09.366 [ObserveOn-1] INFO o.t.ThreadedObsTest - Got root 1 21:03:09.872 [ObserveOn-1] INFO o.t.ThreadedObsTest - Got root 2 21:03:10.376 [ObserveOn-1] INFO o.t.ThreadedObsTest - Got root 3 The emissions are now back on the main thread but the subscriptions are being processed in a threadpool. That is the difference, when subscribeOn is used the emissions are performed on the specified Scheduler, when observeOn is used the subscriptions are performed are on the specified scheduler! And the output when both are specified is equally predictable. Now in all cases I had created a Scheduler using a ThreadPool with 5 threads but only 1 of the threads has really been used both for emitting values and for processing subscriptions, this is actually the normal behavior of Observables. If you want to make more efficient use of the Threadpool, one approach may be to create multiple Observable's, say for eg, if I have a service which returns pages of data this way: public Observable getPages(int totalPages) { return Observable.create(new Observable.OnSubscribe() { @Override public void call(Subscriber subscriber) { logger.info("Getting pages"); for (int i = 1; i <= totalPages; i++) { subscriber.onNext(i); } subscriber.onCompleted(); } }); } and another service which acts on each page of the data: public Observable actOnAPage(int pageNum) { return Observable.create(s -> { Util.delay(200); logger.info("Acting on page {}", pageNum); s.onNext("Page " + pageNum); s.onCompleted(); }); } a way to use a Threadpool to process each page of data would be to chain it this way: getPages(5).flatMap( page -> aService.actOnAPage(page).subscribeOn(Schedulers.from(executor1)) ) .subscribe(s -> { logger.info("Completed Processing page: {}", s); }); see how the subscribeOn is on the each Observable acting on a page. With this change, the output would look like this: 21:15:45.572 [main] INFO o.t.ThreadedObsTest - Getting pages 21:15:45.787 [SubscribeOn-1] INFO o.t.GeneralService - Acting on page 2 21:15:45.787 [SubscribeOn-0] INFO o.t.GeneralService - Acting on page 1 21:15:45.787 [SubscribeOn-4] INFO o.t.GeneralService - Acting on page 5 21:15:45.787 [SubscribeOn-3] INFO o.t.GeneralService - Acting on page 4 21:15:45.787 [SubscribeOn-2] INFO o.t.GeneralService - Acting on page 3 21:15:45.789 [SubscribeOn-1] INFO o.t.ThreadedObsTest - Completed Processing page: Page 2 21:15:45.790 [SubscribeOn-1] INFO o.t.ThreadedObsTest - Completed Processing page: Page 1 21:15:45.790 [SubscribeOn-1] INFO o.t.ThreadedObsTest - Completed Processing page: Page 3 21:15:45.790 [SubscribeOn-1] INFO o.t.ThreadedObsTest - Completed Processing page: Page 4 21:15:45.791 [SubscribeOn-1] INFO o.t.ThreadedObsTest - Completed Processing page: Page 5 Now the threads in the threadpool are being used uniformly.
June 23, 2015
by Biju Kunjummen
· 10,872 Views · 2 Likes
article thumbnail
Five Reasons Why BAM and CEP Have Failed You
[This article was written by Maneesh Joshi] Back in 2005, the concept Business Activity Monitoring (BAM) was coined by Gartner to capture the requirement of visibility into business operations. BAM delivered this visibility through aggregation and summarization of information around business activities. The BAM solution would capture event data, aggregate them into a single store, apply some context on top of the data, and then deliver dashboard-based visibility to business operations managers and sometimes executives. A few questions that a typical BAM solution would answer for the business operations manager at a mortgage lender were: How long does the typical loan application take from submission to approval? Where is the most time spent in the loan application workflow? How many calls does the average call center rep answer per day? Unfortunately, BAM never delivered on it’s promise. I can think of four challenges that made the BAM solution fall short. 1. Vendor-Focused Solutions The first challenge with this approach to BAM was that the solutions were typically built by the large enterprise software vendors that offered it as a complement to their own big and wide technology stacks. This approach made the offerings very vendor-centric and often didn’t cover the heterogeneous set of technologies that most businesses owned. The visibility hence was rather restricted to the large vendor stacks and created information silos and narrow visibility. 2. Too Much Customization The second challenge arose as a result of the fact that no two business processes are alike. There were very few commonalities between business processes for the vendors to build repeatable and scalable pre-packaged dashboards around. In order to build a solution that worked for these processes, heavy customization and services were necessary. For the solution to be meaningful and provide the right kind of visibility, the customization often included intrusive code changes to the application in order to raise business events, whether it was Java code in the Java tier, or the SQL packages in the database tier. 3. No Real-Time Visibility The third challenge was from the lack of real-time nature of the visibility that the BAM technology delivered. By the time the operational data was collected from the sources, aggregated into a database, applied context on, analyzed, and presented into a dashboard, the visibility provided was already stale. In order to address this staleness problem, the notion of complex event processing (CEP) came into being. CEP technologies were purpose built to correlate events and detect patterns across event streams in real-time. 4. Lack of Business Context Despite CEP attempting to solve the staleness problem, it introduced a problem of its own. The events processed by CEP are typically lightweight events and low on context richness. When CEP would attempt to correlate events to detect patterns across disparate streams, it lacked the business context. This lack of context made the solution less effective as no meaningful pattern matching or correlation could be done without the context. The business context needs to be captured at the source when the events are being captured in order to make the correlation relevant. 5. Premature Technology Stack The last and main blocker was that the underlying technology stacks and the surrounding applications were not mature enough to support the vision. For instance, the relational databases that couldn’t capture unstructured events, or the inability to crunch massive volumes of data in real-time at low latencies while applying the context severely restricted the vendors from delivering on the promise. The packaged applications were very monolithic with very little extensibility, which resulted into implementing intrusive code changes to raise business events. To be fair, the vision for BAM and CEP was spot on then and is spot on today. The vision was clearly ahead of its time and the problems it promised to solve very real. Who doesn’t want visibility into their business operations?! In fact BAM and CEP become all the more important is today’s day and age of software-defined businesses. In my next blog post, I will discuss a new approach to BAM. I will also review as to how the technology and application stacks have evolved, and why you should consider revisiting your opinions about BAM and CEP use cases.
June 23, 2015
by Maneesh Joshi
· 1,315 Views
article thumbnail
Percona Monitoring Plugins 1.1.5 Release
[This article was written by Roman Vynar] Percona is glad to announce the release ofPercona Monitoring Plugins1.1.5. Changelog: Added more DB instance classes to pmp-check-aws-rds.py (issue 1398911) Added configurable query period and average time to pmp-check-aws-rds.py (issue 1436943) Added region support to pmp-check-aws-rds.py (issue 1442980) Added an option to alert when server is not configured as replica to pmp-check-mysql-replication-delay (issue 1357017) Improved usage of lock-free SHOW SLAVE STATUS query (issue 1380690) Fixed reporting of slave lag in ss_get_mysql_stats.php (issue 1389769) We have also moved the code to Githubhttps://github.com/percona/percona-monitoring-pluginsbut the bug tracker is still on Launchpadhttps://bugs.launchpad.net/percona-monitoring-plugins. A new tarball is available fromdownloads areaor in packages from oursoftware repositories. The plugins are fully supported for customers with aPercona Supportcontract and free installation services are provided as part of some contracts. In addition as part ofPercona’s Remote DBAinstallation and setup of these tools are included with our services. You can find links to the documentation,forumsand more at theproject homepage.
June 23, 2015
by Peter Zaitsev
· 1,119 Views
article thumbnail
Neo4j: The Foul Revenge Graph
Last week I was showing the foul graph to my colleague Alistair who came up with the idea of running a ‘foul revenge’ query to find out which players gained revenge for a foul with one of their own later in them match. Queries like this are very path centric and therefore work well in a graph. To recap, this is what the foul graph looks like: The first thing that we need to do is connect the fouls in a linked list based on time so that we can query their order more easily. We can do this with the following query: MATCH (foul:Foul)-[:COMMITTED_IN_MATCH]->(match) WITH foul,match ORDER BY match.id, foul.sortableTime WITH match, COLLECT(foul) AS fouls FOREACH(i in range(0, length(fouls) -2) | FOREACH(foul1 in [fouls[i]] | FOREACH (foul2 in [fouls[i+1]] | MERGE (foul1)-[:NEXT]->(foul2) ))); This query collects fouls grouped by match and then adds a ‘NEXT’ relationship between adjacent fouls. The graph now looks like this: Now let’s find the revenge foulers in the Bayern Munich vs Barcelona match. We’re looking for the following pattern: This translates to the following cypher query: match (foul1:Foul)-[:COMMITTED_AGAINST]->(app1)-[:COMMITTED_FOUL]->(foul2)-[:COMMITTED_AGAINST]->(app2)-[:COMMITTED_FOUL]->(foul1), (player1)-[:MADE_APPEARANCE]->(app1), (player2)-[:MADE_APPEARANCE]->(app2), (foul1)-[:COMMITTED_IN_MATCH]->(match:Match {id: "32683310"})<-[:COMMITTED_IN_MATCH]-(foul2) WHERE (foul1)-[:NEXT*]->(foul2) RETURN player2.name AS firstFouler, player1.name AS revengeFouler, foul1.time, foul1.location, foul2.time, foul2.location I’ve added in a few extra parts to the pattern to pull out the players involved and to find the revenge foulers in a specific match – the Bayern Munich vs Barcelona Semi Final 2nd leg. We end up with the following revenge fouls: We can see here that Dani Alves actually gains revenge on Bastian Schweinsteiger twice for a foul he made in the 10th minute. If we tweak the query to the following we can get a visual representation of the revenge fouls as well: match (foul1:Foul)-[:COMMITTED_AGAINST]->(app1)-[:COMMITTED_FOUL]->(foul2)-[:COMMITTED_AGAINST]->(app2)-[:COMMITTED_FOUL]->(foul1), (player1)-[:MADE_APPEARANCE]->(app1), (player2)-[:MADE_APPEARANCE]->(app2), (foul1)-[:COMMITTED_IN_MATCH]->(match:Match {id: "32683310"})<-[:COMMITTED_IN_MATCH]-(foul2), (foul1)-[:NEXT*]->(foul2) RETURN * At the moment I’ve restricted the revenge concept to single matches but I wonder whether it’d be more interesting to create a linked list of fouls which crosses matches between teams in the same season. The code for all of this is on github – the README is a bit sketchy at the moment but I’ll be fixing that up soon.
June 23, 2015
by Mark Needham
· 1,042 Views
article thumbnail
Lucene SIMD Codec Benchmark and Future Steps
We are happy to share results of our Lucene SIMD research announced earlier. Ivan integrated https://github.com/lemire/simdcomp as Lucene Codec and we could observe 18% gain on standard Lucene benchmark. Here are the fork, deck, recording from BerlinBuzzwords. Tech notes The prototype is limited to postings (IndexOptions.DOCS), so far it doesn’t support freqs, positions, payloads. Thus, full idf-tf scoring is not possible so far. The heap problem Currently, the bottleneck of the search performance is the scoring heap. Heap is hard for vectorization, and even hard to compute with regular instructions. Thus, benchmark retrieves only top 10 docs to limit efforts for managing heap. Here is a profiler snapshot for the default Lucene code, decoding takes more than collecting. This is hotspots with the SIMD codec, note that collecting is prevailing now and ForUtil takes relatively smaller time for decoding. Edge cases There are few special code paths which bypass generic FOR decoding which make it harder to observe vectorization gain. Very dense stopwords postings are encoded as a sequence of increasing numbers with by just specifying length of the sequence (see ForUtil.ALL_VALUES_EQUAL). Thus, we excluded stopwords from the benchmark to better observe the gain in FOR decoding. Another edge case is shortening postings on high segmentation. FOR compression is applied on blocks, and remaining tail is encoded by vInt. Thus, to observe the gain in FOR decoding, we merge segments to the single one. Due to the same reason, rare terms with short postings list is not a good use case to show a gain. Further Plans Here are some directions which we consider: provide codec and benchmark as a separate modules; apply SIMD codec for DocValues and Norms - it should improve generic sorting, scoring and faceting. Because ordinals in DocValues are not increasing like postings, https://github.com/lemire/FastPFor should be incorporated; complete codec for supporting frequencies, offsets and positions to make it fully functional; presumably, SIMD facet component might get some gain from vectorization, however decoding ordinals might not be the biggest problem in faceting, like it’s described here; execute binary operations like intersections on compressed data with SIMD instructions https://github.com/lemire/SIMDCompressionAndIntersection; native code might access mmapped index files without boundary checks or copying to heap arrays; implementing roaring bitmaps might help with dense postings; Which of of those directions are relevant your challenges? Leave a comment below! Here are still questions to clarify: will critical natives work for Java 9 and further? couldn’t it happen that vectorization heuristic by JIT makes explicit SIMD codec redundant? We’d like to thank all people who contributed their researches and let us to conduct ours.
June 23, 2015
by Mikhail Khludnev
· 1,972 Views
article thumbnail
Opsmatic Expands Its "Single Source of Truth" Live State Monitoring Capabilities for Larger Enterprises
Opsmatic Inc., a company with a focus on creating tools to improve the effectiveness of development and operations teams, announced today the expansion of its live-state monitoring service to include Enterprise and On-Premises Editions. Opsmatic officially came out of stealth last month and continues to deliver on the promise of supporting the needs of DevOps teams, whether in the cloud or inside a corporate firewall. The Opsmatic live-state monitoring service is the only solution that provides a precise, real-time picture of the detailed configuration and changes that affect an enterprise’s computing infrastructure. The new offerings include all the features of the Professional Edition (announced last month), with the addition of a single sign-on and dedicated support in the Enterprise and On-Premises Editions. The On-Premises Edition is designed for customers with isolated infrastructure who require an internally deployed solution, while leveraging the same real-time visibility to quickly troubleshoot problems and reduce costly downtime. Opsmatic services are delivered through a purpose-built, intelligent data platform which enables customers to easily integrate events from other services for greater context (PagerDuty, Nagios, Zabbix), incorporate their own custom event data (deployment events, backups, etc.); and extend their live state host data to include custom configuration and state data from their own services to provide deeper, more complete insight. Alerts can also be posted to Slack, HipChat, DataDog and PagerDuty, to better support team collaboration and communication. “Our new single sign-on capability gives the entire technical team access to a central source of truth, reducing the number of configuration-related issues while increasing team velocity,” said Jim Stoneham, CEO, Opsmatic. “Our customers have said that incident triage that used to take them hours now takes minutes.” Opsmatic live-state monitoring features include: Real-time insight The Opsmatic service monitors the state of every host in real-time, providing a current and accurate picture of the configuration, as well as an instantaneous feed of any changes happening to that host. Any variation, or “drift” in configuration across host groups is also immediately visible to enable teams to fix minor issues before they escalate into downtime events, saving hours of detective work and remediation. Infrastructure search and Assertions Live-state inventory data can be instantly searched to find vulnerable packages, to identify every version of an open-source package that is deployed, or find hosts that are running a specific service. Specific policies (“Assertions”) can be easily defined and run against live-state data to enforce dependencies, verify configuration, or instantly identify potential issues. Customers can also add internal service configuration and other types of data with a simple inject utility to provide deeper service-level checks. Configuration management monitoring Deep integrations with popular Configuration Management tools from Chef, Puppet, Ansible, SaltStack, as well as Docker, enable tracking and reporting of automation runs, file integrity monitoring, and detailed visibility into the key host attributes set by each run. In addition, Opsmatic reaches beyond the policies deployed through the CM tool to track the entire host and report on changes made outside automation runs. Intelligent alerts Using Assertions and saved searches, Opsmatic gives teams control over alert noise and the fatigue it can cause, enabling them to focus on the changes or conditions that really matter. Any alert can be classified by host or host group, and can be fed into specific chat channels (Slack, HipChat), or emailed to the right person on team to investigate the issue. Robust Software-as-a-Service The Professional and Enterprise Editions are delivered as cloud-based services, supporting any cloud infrastructure, datacenter, or hybrid environment across a range of OS platforms. The services are hosted in a hardened data center with SAS 70 Type II and SSAE 16 certifications and 24x7 monitoring. Availability Opsmatic Enterprise Edition is sold as a monthly subscription, with billing based on usage: $7 per host, per month, based on the peak number of hosts being monitored each month. The Opsmatic On-Premises Edition is sold as a yearly contract by quote at [email protected]. The company offers an unlimited-use, 30-day free trial of Opsmatic Professional that is available at www.opsmatic.com/signup. No credit card is required for the free trial. General inquiries should be directed to [email protected]. About Opsmatic Inc. Opsmatic provides real-time visibility of any change in the live state of computing infrastructure and intelligently alerts users before trouble begins. The SaaS service is built on an underlying data platform with a robust API, and is integrated with popular monitoring and code automation tools to give customers complete context and provide the shared visibility required by modern DevOps teams. Founded in 2013, the Opsmatic team comprises experienced development and operations professionals who were involved at the beginning of the DevOps movement at major web-scale companies. The company is backed by leading investors in the cloud technology space, including AME Cloud Ventures (Jerry Yang), Freestyle Ventures, Illuminate Ventures and Index Ventures. For more info, please visit opsmatic.com or follow @Opsmatic on Twitter.
June 23, 2015
by Jim Rossner
· 878 Views
article thumbnail
Opsmatic Expands Its "Single Source of Truth" Live State Monitoring Capabilities for Large Enterprises
Last month we shared the news about the debut Opsmatic and their live state monitoring service, a solution that delivers a precise, real-time picture of the detailed configuration – as well as changes that affect a computing infrastructure. We wanted to let you know that Opsmatic continues to expand its service capabilities with the announcement of two new versions. The Enterprise version of the Opsmatic service includes all the features we discussed last month in their Professional edition with the addition of single sign-on and dedicated support. The On-Premises edition embodies features contained in the Enterprise version in a solution designed for customers with an isolated infrastructure who require an internally-deployed solution. Details of Opsmatic’s new service offerings are outlined in the press release below. Should you have any questions, Opsmatic would be happy to respond to them.
June 23, 2015
by Jim Rossner
· 920 Views
article thumbnail
How to Start One Release From Another With XL Release
XL Release is a great tool to orchestrate releases. Sometimes we might want XL Release to orchestrate which releases we start. If this sounds kind of recursive, let’s examine a use case that was brought to me recently. The customer had a couple of release templates that might get started as part of their general release. Specifically, they talked about a release for their distributed systems and another release for their mainframes. They wanted to have one of the steps in the first phase of their master release determine if the “distributed” and “mainframe” releases should be started. With a little scripting and using a recent blog (Using XL Release Gate Task for Deciding Future Tasks) we can make one release start another. First lets setup our two templates that will be started by the master template. For our purposes here they don’t have to be very complicated. The first template will be for our distributed systems as follows: Then we will add our template for mainframe installs as follows: Finally, we will add a master template which we will start both. Depending on the path of the master template we can optionally start either one or both of the other two templates. Our master template will be as follows: In the Master template, the first step is a gate to see which releases we need to start from this template. We are using the gate as a conditional step to decide future tasks. For more information about this technique read the blog “Using XL Release Gate Task for Deciding Future Tasks“. The second step is just a script to print out what was set in the “Determine Types of Installs” step. Next, the “Script” step actually determines which templates we selected in the first step and starts those releases. The code for the “Script” step is as follows: import com.xebialabs.xlrelease.api.v1.forms # def gatesBeforeTask(task): gatesList = [] for item in phase.tasks: if str(item.getTaskType()) == "xlrelease.GateTask": gatesList.append(item) if item.id == task.id: break return gatesList # End gatesBeforeTask # gates = gatesBeforeTask(task) conditions = gates[0].getConditions() # for condition in conditions: if condition.title == "isDistributed" and condition.isChecked(): templateName="Blog-Distributed" template = templateApi.getTemplates( templateName ) print "Name = %s \n" % templateName print "ID = %s \n" % template[0].id sr = StartRelease() sr.setReleaseTitle("New Distributed") sr.releaseVariables={"myvar":"1"} r = templateApi.start(template[0].id, sr) print "Release ID = %s \n" % release.id # End if # if condition.title == "isMainframe" and condition.isChecked(): templateName="Blog-Mainframe" template = templateApi.getTemplates( templateName ) print "Name = %s \n" % templateName print "ID = %s \n" % template[0].id sr = StartRelease() sr.setReleaseTitle("New Mainframe") sr.releaseVariables={"yourvar":"1"} r = templateApi.start(template[0].id, sr) print "Release ID = %s \n" % release.id # End if # End for This script task gets a list of “Gate” tasks into the array gates. We know the gate where the types of release templates we want to start is in the first gate, so we get the conditions from that gate (i.e.gate[0]). Since a gate can have multiple conditions, this is an array as well. The script next iterates over the list of conditions looking for the two we are interested in. When we find the proper conditions if they are set the template for that condition is started. Some screen shots from the running Templates are as follows: For this initial gate, if we only want one we need to select skip to move the release along. Once the templates to start have been select the deployment can continue and start the other templates. In this example we only started the “Blog-Distributed” template. We can also open the running “Blog-Distributed” template and see it’s progress as follows: The artifacts from this blog post are also in my Github repo at: https://github.com/zvercodebender/xebialabs-blog-files/tree/master/How_to_Start_one_Release_from_another_Release_in_XL_Release
June 22, 2015
by Rick Broker
· 3,279 Views
article thumbnail
Big Data TCO Lessons From Virtualization Technology Sprawl
The complexity of big data makes it a difficult concept for many to grasp, and utilizing it effectively is one of the biggest challenges businesses face today. There is little doubt that big data offers organizations a number of clear advantages, but applying them across the entire enterprise is one obstacle that can truly be described as formidable, even daunting, to even the most technologically savvy companies. One department might be able to create its own business solutions through big data analytics, while another department might come up with answers of their own, but lack of true coordination and collaboration remains a significant problem. Businesses aren’t without help in this area, however, because they’ve encountered similar problems before. Many companies have encountered issues such as virtualization technology sprawl, and the lessons learned from addressing that problem could prove to be exceptionally valuable when dealing with big data true cost of ownership (TCO). To understand the problem and the solution, we must first look back at the rapid growth of virtualization technology, more specifically server virtualization. As businesses adopted virtualization, the mainframe systems soon diverged into multiple systems. The more popular virtualization became, the more projects were taken on and the more technologies diverged. Larger companies eventually sought technology specialists to work within their areas of expertise. The result of the use of these individual teams was virtualization technology sprawl, an inefficient development that eventually lead to even higher operational costs. For all the benefits virtualization technology offered, many of them were outweighed by the increased demands and greater management complexity that came from technology sprawl. Businesses were quick to come up with new solutions for the problem. The most common was to adopt a converged infrastructure . This strategy directly addressed the higher operational costs that resulted from technology sprawl, basically breaking through the silos by taking multiple technologies and combining them into single stacks for computing, storage, and networking. This made the management of virtualization technology much easier since operational complexity was significantly reduced. In other words, management of this technology was kept at a reasonable size. The same principle can apply to big data management across an entire organization. When it comes to management of big data and hadoop security, it’s easy to get caught up in the immensity of it all. The fact that big data is so versatile and can be applied to so many different use cases also means it can apply to any number of different divisions within a company. This creates silos and a general desire to hold onto data sets. In other words, big data ends up in a sprawl of its own, becoming that much more unwieldy and complicated, which is a major problem for a technology that’s already so complex to begin with. The lesson that every company should take away from the solution to virtualization technology sprawl is the breaking down of barriers to big data management. It all comes down to ready access to all the necessary data no matter what roles an employee may have within a company. Businesses shouldn’t have to worry over the cost it takes to store and process data since the insights gained from big data analytics are particularly valuable. Most importantly, it’s about avoiding big data from getting too big, to the point where it becomes unmanageable and merely adds to the overall operating costs of a company. It’s true that big data introduces more complexity, but businesses that have learned how to store and process it efficiently, sometimes through big data platforms or cloud-based services, are in a more advantageous position than companies still dealing with technology sprawl. The lessons learned from previous problems can indeed play a helpful role in solving the problems many experience today.
June 22, 2015
by Rick Delgado
· 2,016 Views
article thumbnail
FusionExperience announces successful partnership with Cloud Consulting
London, UK – FusionExperience, the business and data solutions provider, today announces the success of its first salesforce.com partnership with Cloud Consulting Ltd. (CCL). CCL was working with an international airline client to migrate a legacy charter and group booking application from one Salesforce.com instance to a new one. Very early on in the project CCL discovered that there were considerable elements of unsupported custom code and that these had to be redesigned and redeveloped. The airline took the opportunity at this stage to request changes and improve the application in line with their new business processes. CCL worked with FusionExperience to migrate the application to the latest salesforce.com environment and re-architected the booking engine functionality and complex pricing algorithms using Apex and VisualForce. For business reasons the airline had a strict project deadline and despite all the unknowns involved the project timescales were maintained and FusionExperience delivered on time and to budget. The airline went live with the application on schedule without any post-production problems or warranty fixes required. They now have an up to date system that has achieved a game changing transformation in the way it does business. Robin James, Platform Evangelist for FusionExperience said; “The ability to seamlessly work with our partners on salesforce.com projects enables rapid scaling of resources and capabilities. This ensures that the client is delighted by the results, yet unaware of the complex extended ecosystem that has been involved. This is facilitated by that fact that we all speak the same salesforce.com language. Cloud Consulting is an ideal partner to work with in this way, as our delivery and technical strengths are well matched with their intimate client facing approach.” Tim Pullen, Managing Director of CCL added: “We already had a close relationship with FusionExperience and it was natural for us to turn to them for help with this suddenly extremely challenging project. The combination of cleaning, segmenting and splitting the data in Salesforce.com, extracting the system configuration and custom code and then creating a new system was tough enough to start but then having to redevelop the application from scratch took it to a new level. Right from the start Robin James and his team took everything in their stride and provided a level of comfort, reassurance, skill and professionalism that we’d never experienced before from other partners. Bear in mind that the old system had no user or technical documentation plus undocumented code and you begin to understand just how good the end result has been for the airline. Thank you Fusion!”
June 22, 2015
by Fran Cator
· 860 Views
article thumbnail
Spring Data Couchbase: Handle Unknown Class
Spring Data Couchbase provides transparent way to save and load Java classes to and from Couchbase. However, if a loaded class contains a property of unknown class, you will receive org.springframework.data.mapping.model.MappingException: No mapping metadata found for java.lang.Object This may happen if, for example, different versions of your code save and load information. In order to handle situation when we want to load an object, which contains another object on unknown class (in a map or list property) we should override the default SPMappingCouchbaseConverter. Let's see how we do this with Spring XML configuration: I replace my old XML: to the following XML: And create the following class: public class MyMappingCouchbaseConverter extends MappingCouchbaseConverter { public MyMappingCouchbaseConverter(final MappingContext, CouchbasePersistentProperty> mappingContext) { super(mappingContext); } @Override protected R read(final TypeInformation type, final CouchbaseDocument source, final Object parent) { if (Object.class == typeMapper.readType(source, type).type) { return null; } return super.read(type, source, parent); } } Now, if loaded object will contain a property of unknown class or an object of unknown class in a list or map, this property or object will be replaced by null. view source print?
June 22, 2015
by Pavel Bernshtam
· 4,122 Views
article thumbnail
Purple WiFi appoints Collin Tan As Regional Manager ASEAN
June 22, 2015: Purple WiFi, the cloud-based Social WiFi software company, today announced the appointment of Collin Tan as Regional Manager, ASEAN reporting to Allen Pan, VP Asia Pacific. He will be based in Singapore and will be responsible for all Purple WiFi’s business in the ASEAN region. He will be working to develop the distributors and reseller channels across countries in ASEAN, namely Singapore, Malaysia, Indonesia, Thailand, Philippines, Vietnam, Brunei, Cambodia, Laos and Myanmar and engage directly with key service providers in these countries. Collin was previously the Managing Director of Singapore start-up, 1Care Global Pte Ltd, providing after sales services, such as equipment protection and extended warranty. Under his leadership 1Care enjoyed tremendous growth with customers in the Asia Pacific region, which includes the world’s Top 2 PC manufacturers. Before joining 1Care Global, Collin spent 10 years with Intel Corporation, serving as Country Manager for Intel Singapore before he left in 2013. Previous roles with Intel include leading the regional OEM team for one of Intel’s largest MNC customers and Manager for the Field Applications Engineers Team based out of Taiwan. Purple WiFi is expanding globally following a $5m investment announced earlier this year. The investment was raised in order to accelerate product development and recruitment of a truly global sales team, which already has strongholds in Europe, Asia-Pacific and the Americas. The WiFi offering focuses on engaging, understanding and delivering value by allowing users to gain free access to a public WiFi network through their existing social media accounts or a short form. The user gets access to family friendly WiFi, while the benefit to the business hosting the service (such as a restaurant, hotel, retailer, museum, sports stadium or shopping mall) is valuable analytic insights into the profiles and movements of their customers and a sophisticated built-in marketing platform. Thousands of venues globally have been secured and deep technology partnerships established, most notably with Cisco, Cisco Meraki, BT and Verizon but also many others. Collin Tan, Regional Manager ASEAN, Purple WiFi, comments: “Purple WiFi provides the perfect solution for companies that wish to monetise their free WiFi, as well as enabling direct targeted marketing to users within its proximity. It also combines the four fastest growing technology sectors of Mobile, Cloud, Social Media and Analytics in a single product, making it extremely valuable as a service and technology organisation.” Allen Pan, VP Asia Pacific, Purple WiFi, comments: “Collin brings the perfect combination of experience and drive to the role and we’re excited to have him onboard. The market in ASEAN is growing quickly and Collin’s in-depth knowledge of the region will allow us to capitalise on the opportunities for Purple WiFi.”
June 22, 2015
by Fran Cator
· 1,057 Views
article thumbnail
ParStream to Present Requirements of an Analytics Platform for IoT at the TDWI Munich Conference 2015
COLOGNE, Germany – June 22, 2015 – ParStream, the IoT analytics company, today announced its participation at the TDWI Munich Conference 2015, one of the largest gatherings of expert Business Intelligence, Big Data and data warehousing leaders and educators in Europe. The conference will take place June 22-24, 2015 at the MOC Order and Event Center in Munich, Germany. Albert Aschauer, Sales Director DACH at ParStream, will present on requirements for an analytics platform for the Internet of Things (IoT) based on real-world use cases from the renewable energy and telecommunications industries. Big Data, fast data, edge analytics and real-time insights are driving new technology innovation to meet the demand for getting more value from IoT data. Additional details on the speaking session are below. What: “Requirements of an Analytics Platform for the Internet of Things” When: Monday, June 22, 2015 at 11:35 a.m. CEST Who: Albert Aschauer, Sales Director DACH at ParStream Where: MOC Munich, Germany – Room F112 To schedule a one-on-one meeting with Albert Aschauer and ParStream at TDWI Munich Conference 2015, send an email to events(at)parstream(dot)com.
June 22, 2015
by Fran Cator
· 1,131 Views
article thumbnail
Optimized Text-Stamp Operations, Enhanced PDF to HTML & DOC Conversion in Java Apps
What's New in this Release? Aspose team is pleased to announce the release of Aspose.Pdf for Java 10.3.0. It provides better license initialization capabilities. As shared in earlier blogs, we introduced a method clear() in com.aspose.pdf.MemoryCleaner class, which provides Memory Cleanup features so that memory is set free from unused objects. This method optimizes API performance as system resources are released, leaving API with sample resources to perform various PDF creation and manipulation operations. In this new release, we have also optimized TextStamp operation. Other than these improvements, a better support for UTF8 and UTF16 characters is provided, when converting TEXT files to PDF format. Cross file format conversions are one of the salient features offered by our API. Therefore, the PDF to HTML, the PDF to DOC, transformation of PDF pages to Image format as well as the Image to PDF conversion features are specifically improved. Among these features, the text manipulation is also improved while searching and replacing TextFragments inside the PDF file. Starting this new release, we are providing a single code base (.jar) file targeting JDK 1.6 and its compatible with JDK 1.6, 1.7 and later versions. Some important improved features included in this release are given below Increase TextStamp creation performance com.aspose.pdf.MemoryCleaner.clear() method nulls the license object as well Aspose.Pdf 9.5.2 to HTML conversion issue on particular file UTF-8 characters not appearing properly License implementation difference in 9.3.0 and 10.2.0 with Java web application java.awt.HeadlessException in Headless Mode PDF to Image - Conversion process stucks in infinite loop Text to PDF: Incorrect rendering of UTF8 text in output PDF Text to PDF: Incorrect rendering of UTF16 text in output PDF gets wrong coordinates of seached Text Image to PDF: API throws IllegalArgumentException PDF to PNG - Process hangs during conversion PDF to HTML: text is distorted in output HTML PDF to DOC: Text renders incorrectly Image to PDF throws IllegalArgumentException exception PDF to HTML - StringIndexOutOfBoundsException being generated PDF to Image - conversion method stuck and never returns Hyperlink text/contents are not visible in PDF file Overview: Aspose.Pdf for Java Aspose.Pdf is a Java PDF component to create PDF documents without using Adobe Acrobat. It supports Floating box, PDF form field, PDF attachments, security, Foot note & end note, Multiple columns document, Table of Contents, List of Tables, Nested tables, Rich text format, images, hyperlinks, JavaScript, annotation, bookmarks, headers, footers and many more. Now you can create PDF by API, XML and XSL-FO files. It also enables you to converting HTML, XSL-FO and Excel files into PDF. Homepage of Aspose.Pdf for Java Download Aspose.Pdf for Java
June 22, 2015
by David Zondray
· 1,075 Views
article thumbnail
Social customer care ebook
Think about the last time something really aggravated you, whether it was a slow Internet connection, long store lines, or a rude cashier. Did you vow to go home and call an 800 number, punch through a bunch of option keys, and wait to talk to a customer service rep? Or did you take out your smart phone and hammer out your frustrations in 140 characters or less? Odds are you’re like the millions of consumers who express their grievances with friends, family, and colleagues on Twitter, Facebook, YouTube, or a host of other social sites. With more than 230 million people on Twitter and a billion or more on Facebook, companies now understand the importance of providing customer service over social media. According to a 2014 Forrester report, 62 percent of businesses believe they will lose ground if they don’t adopt social customer service technologies. Companies slow to embrace social media for customer service, also known as social care, are missing an opportunity to build their brands and customer loyalty. Ignoring customer problems on social media can spark a raging fire of discontent. But by connecting with customers on social media, you can quickly respond and resolve issues in front of thousands of other prospective clients. A study by the International Customer Management Institute shows 61 percent of consumers who received social care were more satisfied with their support. And 58 percent said social care increased their customer loyalty. Are you ready to advance your customer support program to the social community or are you willing to sit on hold while your customers begin looking elsewhere? We’ve created an eBook, “Social Customer Care: How to Use Social Media to Improve Customer Support,” to explore the reasons for adding social care to your customer service programs. It also provides tips from industry experts on how to get there. Like this post? Click here to subscribe to our blog and receive the latest content on social learning, customer support, sales enablement, or all three.
June 22, 2015
by Bloomfire Marketing
· 1,028 Views · 1 Like
article thumbnail
Making litigation more affordable
Last year some data from the Citizens Advise Bureau revealed that 7 out of 10 potentially successful employment cases are not being pursued, with a good 50 percent of those being down to financial issues. Whilst it’s tempting to think that we are all equal in front of the law, there remains a distinct sense that we are anything but. It’s a major reason why companies such as Logikcull are trying to make the whole process easier and more efficient. It’s believed that the e-discovery process can contribute to around 70 percent of the costs of any legal proceeding, so reducing the time involved in that can be a huge cost saver. Using the crowd Other organizations are attempting to make the legal process more affordable by recruiting the crowd to help meet the legal costs involved. For instance, I wrote about LexShares towards the end of last year, who are a kind of crowd based investment site. You can ‘invest’ in a particular case, thus giving the plaintiff funds to pursue their case. If the case is successful, the backer gets their money back plus a bit of the damages. If the case fails, then they lose their money. Another crowd based venture launched in the UK recently. The site, called CrowdJustice, aims to provide funding to cases that would normally struggle to do so. Supporting public interest cases The site was founded by Julia Salasky, who previously worked for the UN, and aims to specialize in so called public interest cases. “CrowdJustice allows communities to band together to access the courts to protect their communal assets – like their local hospital – or shared values – like human rights. Successive governments have made access to justice harder and more expensive but we are using the power of the crowd to try and stem the tide,” she says. She suggests that cuts to legal aid has made it harder for poorer people to access adequate legal protection, especially when it comes to challenging large institutions. This is especially so when the end game doesn’t necessarily result in a large payout. This could include, for instance, the destruction of a local bird sanctuary or even much larger issues such as torture. Despite effecting huge numbers of people, it is often very difficult for communities to channel their energies towards fighting the case collectively. As such, these kind of cases typically require a determined individual to pursue the cause on their own. The hope is that the CrowdJustice platform will make this considerably easier. Whether it’s CrowdJustice or LexStorm or Logikcull, there are certainly a wide range of projects aiming to change the legal industry for the better. It will be fascinating to watch them as they unfold and witness the impact they have. Original post
June 22, 2015
by Adi Gaskell
· 1,021 Views
article thumbnail
Study casts doubts on the effectiveness of online learning
As the MOOC revolution gathered pace, there was a widespread hope that it would prompt a major change in how tertiary education was provided. After all, they emerged in an environment where course fees were mushrooming, and many young people were graduating with enormous debts. Could online courses therefore provide a more efficient means of getting a degree? Whilst there is still a largely optimistic air around MOOCs, a recent study provides a cautionary tale. The paper compares the performance of community college students who undertook their courses online versus more traditional classroom based studies. About the study The focus of the research was the Californian Community College system, which ‘processes’ 2.3 million students each year. The study found that students on online courses achieved both lower grades and completion rates than their peers on more traditionally delivered courses. “We found the same pattern of results across all course types,” the authors say. This drop off in performance was particularly pronounced when students were undertaking courses outside of the normal academic year. They also appeared to suffer when the online segment of the student body for a class was in a relative minority. “The consistency of our results is important from a policy perspective,” the authors say. “Policymakers in California and other states are interested in exploring whether online courses can be used to expand instruction and improve outcomes, but there may be costs to this strategy.” Of course, this isn’t the first study into the success, or otherwise, of online courses. Last year, for instance, saw a study of student success at MIT. When the researchers tested both MOOC students on a MIT physics class and their offline peers, they found that the knowledge learned via the MOOC was greater than that in the traditional, lecture based course. What’s more, they found that even those MOOC students that were not at all well prepared for their course (ie those with low scores before the course started), ended up learning just as well as their fellow students. The rate of improvement was almost equal regardless of the skill level at the outset of the course. Another study highlighted the large spread of people that typically enroll for online courses, and the challenges this creates on how to motivate and engage such a diverse body. They identified five distinct type of student: Bystandars are students who are probably at the lowest end of the engagement ladder. They’ll sign up for a course, but then not really engage with it. Some might not even log-in to the course once it begins. Collectors on the other hand are slightly further up the ladder. They’ll consume the video content provided by the course, but they won’t do a great deal of interaction with fellow students. Viewers are similar to the collectors in that their primary means of engagement with the course is via the lectures. Despite watching the content however, the viewer is unlikely to complete many of the assignments. Solvers tend to be polar opposite to the viewers. They’ll do a lot of the assignments, without necessarily having watched the lectures beforehand. All rounders are undoubtedly the holy grail however, as these are the people that do it all. They’ll watch the lectures and do the assignments. Whether students at community colleges fit into one or other of these groups is difficult to determine, but I suspect a much wider exploration is required in order to draw particularly firm conclusions. Original post
June 22, 2015
by Adi Gaskell
· 1,006 Views
article thumbnail
Thread Pools in NGINX Boost Performance 9x!
Introduction [This article was written by Valentin Bartenev] It’s well known that NGINX uses an asynchronous, event-driven approach to handling connections. This means that instead of creating another dedicated process or thread for each request (like servers with a traditional architecture), it handles multiple connections and requests in one worker process. To achieve this, NGINX works with sockets in a non-blocking mode and uses efficient methods such as epoll and kqueue. Because the number of full-weight processes is small (usually only one per CPU core) and constant, much less memory is consumed and CPU cycles aren’t wasted on task switching. The advantages of such an approach are well-known through the example of NGINX itself. It successfully handles millions of simultaneous requests and scales very well. Each process consumes additional memory, and each switch between them consumes CPU cycles and trashes L-caches But the asynchronous, event-driven approach still has a problem. Or, as I like to think of it, an “enemy”. And the name of the enemy is: blocking. Unfortunately, many third-party modules use blocking calls, and users (and sometimes even the developers of the modules) aren’t aware of the drawbacks. Blocking operations can ruin NGINX performance and must be avoided at all costs. Even in the current official NGINX code it’s not possible to avoid blocking operations in every case, and to solve this problem the new “thread pools” mechanism was implemented in NGINX version 1.7.11. What it is and how it supposed to be used, we will cover later. Now let’s meet face to face with our enemy. The Problem First, for better understanding of the problem a few words about how NGINX works. In general, NGINX is an event handler, a controller that receives information from the kernel about all events occurring on connections and then gives commands to the operating system about what to do. In fact, NGINX does all the hard work by orchestrating the operating system, while the operating system does the routine work of reading and sending bytes. So it’s very important for NGINX to respond fast and in a timely manner. The events can be timeouts, notifications about sockets ready to read or to write, or notifications about an error that occurred. NGINX receives a bunch of events and then processes them one by one, doing the necessary actions. Thus all the processing is done in a simple loop over a queue in one thread. NGINX dequeues an event from the queue and then reacts to it by, for example, writing or reading a socket. In most cases, this is extremely quick (perhaps just requiring a few CPU cycles to copy some data into memory) and NGINX proceeds through all of the events in the queue in an instant. All processing is done in a simple loop by one thread But what will happen if some long and heavy operation has occurred? The whole cycle of event processing will get stuck waiting for this operation to finish. So, by saying “a blocking operation” we mean any operation that stops the cycle of handling events for a significant amount of time. Operations can be blocking for various reasons. For example, NGINX might be busy with lengthy, CPU-intensive processing, or it might have to wait to access a resource (such as a hard drive, or a mutex or library function call that gets responses from a database in a synchronous manner, etc.). The key point is that while processing such operations, the worker process cannot do anything else and cannot handle other events, even if there are more system resources available and some events in the queue could utilize those resources. Imagine a salesperson in a store with a long queue in front of him. The first guy in the queue asks for something that is not in the store but is in the warehouse. The salesperson goes to the warehouse to deliver the goods. Now the entire queue must wait a couple of hours for this delivery and everyone in the queue is unhappy. Can you imagine the reaction of the people? The waiting time of every person in the queue is increased by these hours, but the items they intend to buy might be right there in the shop. Nearly the same situation happens with NGINX when it asks to read a file that isn’t cached in memory, but needs to be read from disk. Hard drives are slow (especially the spinning ones), and while the other requests waiting in the queue might not need access to the drive, they are forced to wait anyway. As a result, latencies increase and system resources are not fully utilized. Some operating systems provide an asynchronous interface for reading and sending files and NGINX can use this interface (see the aio directive). A good example here is FreeBSD. Unfortunately, we can’t say the same about Linux. Although Linux provides a kind of asynchronous interface for reading files, it has a couple of significant drawbacks. One of them is alignment requirements for file access and buffers, but NGINX handles that well. But the second problem is worse. The asynchronous interface requires the O_DIRECT flag to be set on the file descriptor, which means that any access to the file will bypass the cache in memory and increase load on the hard disks. That definitely doesn’t make it optimal for many cases. To solve this problem in particular, thread pools were introduced in NGINX 1.7.11. They are not included by default in NGINX Plus yet, but contact sales if you’d like to try a build of NGINX Plus R6 that has thread pools enabled. Now let’s dive into what thread pools are about and how they work. Thread Pools Let’s return to our poor sales assistant who delivers goods from a faraway warehouse. But he has become smarter (or maybe he became smarter after being beaten by the crowd of angry clients?) and hired a delivery service. Now when somebody asks for something from the faraway warehouse, instead of going to the warehouse himself, he just drops an order to a delivery service and they will handle the order while our sales assistant will continue serving other customers. Thus only those clients whose goods aren’t in the store are waiting for delivery, while others can be served immediately. In terms of NGINX, the thread pool is performing the functions of the delivery service. It consists of a task queue and a number of threads that handle the queue. When a worker process needs to do a potentially long operation, instead of processing the operation by itself it puts a task in the pool’s queue, from which it can be taken and processed by any free thread. It seems then we have another queue. Right. But in this case the queue is limited by a specific resource. We can’t read from a drive faster than the drive is capable of producing data. Now at least the drive doesn’t delay processing of other events and only the requests that need to access files are waiting. The “reading from disk” operation is often used as the most common example of a blocking operation, but actually the thread pools implementation in NGINX can be used for any tasks that aren’t appropriate to process in the main working cycle. At the moment, offloading to thread pools is implemented only for two essential operations: the read() syscall on most operating systems and sendfile() on Linux. We will continue to test and benchmark the implementation, and we may offload other operations to the thread pools in future releases if there’s a clear benefit. Benchmarking It’s time to move from theory to practice. To demonstrate the effect of using thread pools we are going to perform a synthetic benchmark that simulates the worst mix of blocking and non-blocking operations. It requires a data set that is guaranteed not to fit in memory. On a machine with 48 GB of RAM, we have generated 256 GB of random data in 4-MB files, and then have configured NGINX 1.9.0 to serve it. The configuration is pretty simple: worker_processes 16; events { accept_mutex off; } http { include mime.types; default_type application/octet-stream; access_log off; sendfile on; sendfile_max_chunk 512k; server { listen 8000; location / { root /storage; } } } As you can see, to achieve better performance some tuning was done: logging and accept_mutex were disabled,sendfile was enabled, and sendfile_max_chunk was set. The last directive can reduce the maximum time spent in blocking sendfile() calls, since NGINX won’t try to send the whole file at once, but will do it in 512-KB chunks. The machine has two Intel Xeon E5645 (12 cores, 24 HT-threads in total) processors and a 10-Gbps network interface. The disk subsystem is represented by four Western Digital WD1003FBYX hard drives arranged in a RAID10 array. All of this hardware is powered by Ubuntu Server 14.04.1 LTS. The clients are represented by two machines with the same specifications. On one of these machines, wrk creates load using a Lua script. The script requests files from our server in a random order using 200 parallel connections, and each request is likely to result in a cache miss and a blocking read from disk. Let’s call this load the random load. On the second client machine we will run another copy of wrk that will request the same file multiple times using 50 parallel connections. Since this file will be frequently accessed, it will remain in memory all the time. In normal circumstances, NGINX would serve these requests very quickly, but performance will fall if the worker processes are blocked by other requests. Let’s call this load the constant load. The performance will be measured by monitoring throughput of the server machine using ifstat and by obtaining wrkresults from the second client. Now, the first run without thread pools does not give us very exciting results: % ifstat -bi eth2 eth2 Kbps in Kbps out 5531.24 1.03e+06 4855.23 812922.7 5994.66 1.07e+06 5476.27 981529.3 6353.62 1.12e+06 5166.17 892770.3 5522.81 978540.8 6208.10 985466.7 6370.79 1.12e+06 6123.33 1.07e+06 As you can see, with this configuration the server is able to produce about 1 Gbps of traffic in total. In the output from top, we can see that all of worker processes spend most of the time in blocking I/O (they are in a D state): top - 10:40:47 up 11 days, 1:32, 1 user, load average: 49.61, 45.77 62.89 Tasks: 375 total, 2 running, 373 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 67.7 id, 31.9 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 49453440 total, 49149308 used, 304132 free, 98780 buffers KiB Swap: 10474236 total, 20124 used, 10454112 free, 46903412 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4639 vbart 20 0 47180 28152 496 D 0.7 0.1 0:00.17 nginx 4632 vbart 20 0 47180 28196 536 D 0.3 0.1 0:00.11 nginx 4633 vbart 20 0 47180 28324 540 D 0.3 0.1 0:00.11 nginx 4635 vbart 20 0 47180 28136 480 D 0.3 0.1 0:00.12 nginx 4636 vbart 20 0 47180 28208 536 D 0.3 0.1 0:00.14 nginx 4637 vbart 20 0 47180 28208 536 D 0.3 0.1 0:00.10 nginx 4638 vbart 20 0 47180 28204 536 D 0.3 0.1 0:00.12 nginx 4640 vbart 20 0 47180 28324 540 D 0.3 0.1 0:00.13 nginx 4641 vbart 20 0 47180 28324 540 D 0.3 0.1 0:00.13 nginx 4642 vbart 20 0 47180 28208 536 D 0.3 0.1 0:00.11 nginx 4643 vbart 20 0 47180 28276 536 D 0.3 0.1 0:00.29 nginx 4644 vbart 20 0 47180 28204 536 D 0.3 0.1 0:00.11 nginx 4645 vbart 20 0 47180 28204 536 D 0.3 0.1 0:00.17 nginx 4646 vbart 20 0 47180 28204 536 D 0.3 0.1 0:00.12 nginx 4647 vbart 20 0 47180 28208 532 D 0.3 0.1 0:00.17 nginx 4631 vbart 20 0 47180 756 252 S 0.0 0.1 0:00.00 nginx 4634 vbart 20 0 47180 28208 536 D 0.0 0.1 0:00.11 nginx 4648 vbart 20 0 25232 1956 1160 R 0.0 0.0 0:00.08 top 25921 vbart 20 0 121956 2232 1056 S 0.0 0.0 0:01.97 sshd 25923 vbart 20 0 40304 4160 2208 S 0.0 0.0 0:00.53 zsh In this case the throughput is limited by the disk subsystem, while the CPU is idle most of the time. The results from wrkare also very low: Running 1m test @ http://192.0.2.1:8000/1/1/1 12 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 7.42s 5.31s 24.41s 74.73% Req/Sec 0.15 0.36 1.00 84.62% 488 requests in 1.01m, 2.01GB read Requests/sec: 8.08 Transfer/sec: 34.07MB And remember, this is for the file that should be served from memory! The excessively large latencies are because all the worker processes are busy with reading files from the drives to serve the random load created by 200 connections from the first client, and cannot handle our requests in good time. It’s time to put our thread pools in play. For this we just add the aio threads directive to the location block: location / { root /storage; aio threads; } and ask NGINX to reload its configuration. After that we repeat the test: % ifstat -bi eth2 eth2 Kbps in Kbps out 60915.19 9.51e+06 59978.89 9.51e+06 60122.38 9.51e+06 61179.06 9.51e+06 61798.40 9.51e+06 57072.97 9.50e+06 56072.61 9.51e+06 61279.63 9.51e+06 61243.54 9.51e+06 59632.50 9.50e+06 Now our server produces 9.5 Gbps, compared to ~1 Gbps without thread pools! It probably could produce even more, but it has already reached the practical maximum network capacity, so in this test NGINX is limited by the network interface. The worker processes spend most of the time just sleeping and waiting for new events (they are in S state in top): top - 10:43:17 up 11 days, 1:35, 1 user, load average: 172.71, 93.84, 77.90 Tasks: 376 total, 1 running, 375 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.2 us, 1.2 sy, 0.0 ni, 34.8 id, 61.5 wa, 0.0 hi, 2.3 si, 0.0 st KiB Mem: 49453440 total, 49096836 used, 356604 free, 97236 buffers KiB Swap: 10474236 total, 22860 used, 10451376 free, 46836580 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 4654 vbart 20 0 309708 28844 596 S 9.0 0.1 0:08.65 nginx 4660 vbart 20 0 309748 28920 596 S 6.6 0.1 0:14.82 nginx 4658 vbart 20 0 309452 28424 520 S 4.3 0.1 0:01.40 nginx 4663 vbart 20 0 309452 28476 572 S 4.3 0.1 0:01.32 nginx 4667 vbart 20 0 309584 28712 588 S 3.7 0.1 0:05.19 nginx 4656 vbart 20 0 309452 28476 572 S 3.3 0.1 0:01.84 nginx 4664 vbart 20 0 309452 28428 524 S 3.3 0.1 0:01.29 nginx 4652 vbart 20 0 309452 28476 572 S 3.0 0.1 0:01.46 nginx 4662 vbart 20 0 309552 28700 596 S 2.7 0.1 0:05.92 nginx 4661 vbart 20 0 309464 28636 596 S 2.3 0.1 0:01.59 nginx 4653 vbart 20 0 309452 28476 572 S 1.7 0.1 0:01.70 nginx 4666 vbart 20 0 309452 28428 524 S 1.3 0.1 0:01.63 nginx 4657 vbart 20 0 309584 28696 592 S 1.0 0.1 0:00.64 nginx 4655 vbart 20 0 30958 28476 572 S 0.7 0.1 0:02.81 nginx 4659 vbart 20 0 309452 28468 564 S 0.3 0.1 0:01.20 nginx 4665 vbart 20 0 309452 28476 572 S 0.3 0.1 0:00.71 nginx 5180 vbart 20 0 25232 1952 1156 R 0.0 0.0 0:00.45 top 4651 vbart 20 0 20032 752 252 S 0.0 0.0 0:00.00 nginx 25921 vbart 20 0 121956 2176 1000 S 0.0 0.0 0:01.98 sshd 25923 vbart 20 0 40304 3840 2208 S 0.0 0.0 0:00.54 zsh There are still plenty of CPU resources. The results of wrk: Running 1m test @ http://192.0.2.1:8000/1/1/1 12 threads and 50 connections Thread Stats Avg Stdev Max +/- Stdev Latency 226.32ms 392.76ms 1.72s 93.48% Req/Sec 20.02 10.84 59.00 65.91% 15045 requests in 1.00m, 58.86GB read Requests/sec: 250.57 Transfer/sec: 0.98GB The average time to serve a 4-MB file has been reduced from 7.42 seconds to 226.32 milliseconds (33 times less), and the number of requests per second has increased by 31 times (250 vs 8)! The explanation is that our requests no longer wait in the events queue for processing while worker processes are blocked on reading, but are handled by free threads. As long as the disk subsystem is doing its job as best it can serving our random load from the first client machine, NGINX uses the rest of the CPU resources and network capacity to serve requests of the second client from memory. Still Not a Silver Bullet After all our fears about blocking operations and some exciting results, probably most of you already are going to configure thread pools on your servers. Don’t hurry. The truth is that fortunately most read and send file operations do not deal with slow hard drives. If you have enough RAM to store the data set, then an operating system will be clever enough to cache frequently used files in a so-called “page cache”. The “page cache” works pretty well and allows NGINX to demonstrate great performance in almost all common use cases. Reading from the page cache is quite quick and no one can call such operations “blocking.” On the other hand, offloading to a thread pool has some overhead. So if you have a reasonable amount of RAM and your working data set isn’t very big, then NGINX already works in the most optimal way without using thread pools. Offloading read operations to the thread pool is a technique applicable to very specific tasks. It is most useful where the volume of frequently requested content doesn’t fit into the operating system’s VM cache. This might be the case with, for instance, a heavily loaded NGINX-based streaming media server. This is the situation we’ve simulated in our benchmark. It would be great if we could improve the offloading of read operations into thread pools. All we need is an efficient way to know if the needed file data is in memory or not, and only in the latter case should the reading operation be offloaded to a separate thread. Turning back to our sales analogy, currently the salesman cannot know if the requested item is in the store and must either always pass all orders to the delivery service or always handle them himself. The culprit is that operating systems are missing this feature. The first attempts to add it to Linux as the fincore() syscall were in 2010 but that didn’t happen. Later there were a number of attempts to implement it as a new preadv2() syscall with the RWF_NONBLOCK flag (see Non-blocking buffered file read operations and Asynchronous buffered read operations at LWN.net for details). The fate of all these patches is still unclear. The sad point here is that it seems the main reason why these patches haven’t been accepted yet to the kernel is continuous bikeshedding. On the other hand, users of FreeBSD don’t need to worry at all. FreeBSD already has a sufficiently good asynchronous interface for reading files, which you should use instead of thread pools. Configuring Thread Pools So if you are sure that you can get some benefit out of using thread pools in your use case, then it’s time to dive deep into configuration. The configuration is quite easy and flexible. The first thing you should have is NGINX version 1.7.11 or later, compiled with the --with-threads configuration parameter. In the simplest case, the configuration looks very plain. All you need is to include the aio threads directive in the http, server, or location context: aio threads; This is the minimal possible configuration of thread pools. In fact, it’s a short version of the following configuration: thread_pool default threads=32 max_queue=65536; aio threads=default; It defines a thread pool called default with 32 working threads and a maximum length for the task queue of 65536 requests. If the task queue is overloaded, NGINX logs this error and rejects the request: thread pool "NAME" queue overflow: N tasks waiting The error means it’s possible that the threads aren’t able to handle the work as quickly as it is added to the queue. You can try increasing the maximum queue size, but if that doesn’t help, then it indicates that your system is not capable of serving so many requests. As you already noticed, with the thread_pool directive you can configure the number of threads, the maximum length of the queue, and the name of a specific thread pool. The last implies that you can configure several independent thread pools and use them in different places of your configuration file to serve different purposes: http { thread_pool one threads=128 max_queue=0; thread_pool two threads=32; server { location /one { aio threads=one; } location /two { aio threads=two; } } … } If the max_queue parameter isn’t specified, the value 65536 is used by default. As shown, it’s possible to set max_queueto zero. In this case the thread pool will only be able to handle as many tasks as there are threads configured; no tasks will wait in the queue. Now let’s imagine you have a server with three hard drives and you want this server to work as a «caching proxy» that caches all responses from your back ends. The expected amount of cached data far exceeds the available RAM. It’s actually a caching node for your personal CDN. Of course in this case the most important thing is to achieve maximum performance from the drives. One of your options is to configure a RAID array. This approach has its pros and cons. Now with NGINX you can take another one: # We assume that each of the hard drives is mounted on one of the directories: # /mnt/disk1, /mnt/disk2, or /mnt/disk3 accordingly proxy_cache_path /mnt/disk1 levels=1:2 keys_zone=cache_1:256m max_size=1024G use_temp_path=off; proxy_cache_path /mnt/disk2 levels=1:2 keys_zone=cache_2:256m max_size=1024G use_temp_path=off; proxy_cache_path /mnt/disk3 levels=1:2 keys_zone=cache_3:256m max_size=1024G use_temp_path=off; thread_pool pool_1 threads=16; thread_pool pool_2 threads=16; thread_pool pool_3 threads=16; split_clients $request_uri $disk { 33.3% 1; 33.3% 2; * 3; } location / { proxy_pass http://backend; proxy_cache_key $request_uri; proxy_cache cache_$disk; aio threads=pool_$disk; sendfile on; } In this configuration three independent caches are used, dedicated to each of the disks, and three independent thread pools are dedicated to the disks as well. The split_clients module is used for load balancing between the caches (and as a result between the disks), which perfectly fits this task. The use_temp_path=off parameter to the proxy_cache_path directive instructs NGINX to save temporary files into the same directories where the corresponding cache data is located. It is needed to avoid copying response data between the hard drives when updating our caches. All this together allows us to get maximum performance out of the current disk subsystem, because NGINX through separate thread pools interacts with the drives in parallel and independently. Each of the drives is served by 16 independent threads with a dedicated task queue for reading and sending files. I bet your clients like this custom-tailored approach. Be sure that your hard drives like it too. This example is a good demonstration of how flexibly NGINX can be tuned specifically for your hardware. It’s like you are giving instructions to NGINX about the best way to interact with the machine and your data set. And by fine-tuning NGINX in user space, you can ensure that your software, operating system, and hardware work together in the most optimal mode to utilize all the system resources as effectively as possible. Conclusion Summing up, thread pools is a great feature that pushes NGINX to new levels of performance by eliminating one of its well-known and long-time enemies – blocking – especially when we are speaking about really large volumes of content. And there is even more to come. As previously mentioned, this brand-new interface potentially allows offloading of any long and blocking operation without any loss of performance. NGINX opens up new horizons in terms of having a mass of new modules and functionality. Lots of popular libraries still do not provide an asynchronous non-blocking interface, which previously made them incompatible with NGINX. We may spend a lot of time and resources on developing our own non-blocking prototype of some library, but will it always be worth the effort? Now, with thread pools on board, it is possible to use such libraries relatively easily, making such modules without an impact on performance. Stay tuned.
June 22, 2015
by Patrick Nommensen
· 12,713 Views · 1 Like
article thumbnail
Programming for the People: A FutureTalk With Women Who Code [Video]
[This article was written by Christian Sinai] With 25,000 members in 15 countries, Women Who Code is a nonprofit organization dedicated to inspiring women to excel in technology careers. For our latest FutureTalks event, New Relic joined forces with Caterina Paun, co-director of Women Who Code’s Portland chapter, to host a Networking Night that featured half a dozen software engineers talking about their innovative work. Covering a broad range of topics and deploying a wide array of animal photos, the presenters entertained as they educated, making the night a tremendous success. Code is for people It’s a simple truth, but one sometimes forgotten when you’re deep in the trenches of the coding process: Code is for people. And no matter whether your project is personal, internal, or potentially global, it’s important to keep that fact in mind. That was the advice offered by Emily Hyland, senior software engineer at New Relic. A Ruby and JavaScript specialist, Emily believes in “programming for humans.” Or, more specifically, in prioritizing the user experience (UX). Critically, she’s not just talking about the eventual user of your software or app, but also the fellow programmer who may wind up working with your API. “Your computer doesn’t care what your code looks like,” says Emily, “but your colleagues do.” A positive UX depends on simplicity. Also, the user’s ability to form an emotional connection with the code. Sound a little strange? Not to Emily. The more elegant the code—the moresense it makes to the programmer as they navigate its unique components and protocols—the more pleasure they take from working with it. And happy programmers are a whole lot more effective than unhappy ones. Does your code make sense? Emily believes in the principle of “affordance”—the way in which specific qualities or properties of an object define or clarify its intended use. For example, the handle on a coffee cup provides an affordance for holding. When writing code, the terms you use might make perfect sense to you in that particular moment, but may prove incomprehensible to your colleagues later on. By paying attention to the affordance of your code, you can increase its usability down the road. Why? Because when people can tell what something’s for, they’re less afraid to jump in and play with it. Because a consistent interface lets users apply things they’ve already learned, rather than keeping them guessing about what to do. And because when they sense that you designed your API with their personal happiness in mind, they’ll be inspired to make your great work even better. Imagine the end user This all sounds terrific in theory. But how does someone put it into practice? Emily offers a few suggestions, including taking a moment before you dive into the coding process to imagine the eventual users and their goals. Better still, write the README file before you write the code—doing so forces you to think about how the software will actually be used, not just how it will be implemented. If that’s not possible, it’s never too late to think in terms of UX. Step back every so often during the coding process to consider your approach. If you’re in the review phase, you’re in the perfect frame of mind to reflect on what you’ve written. Consistency, simplicity, compliance with established conventions—all are great to prioritize in your mission to make your code as people-friendly as possible. Emily’s was just one of five fascinating presentations you can watch in the video below. The others include Alice Goldfuss on why Docker is so great Katie Leonard and Zoe Kay on the perks and pitfalls of upgrading Ruby on Rails Ashley Puls on monitoring and delivering performance Katherine Wu on moving from ActiveRecord to a service To learn more from these Women Who Code, check out the full FutureTalk video below: For more information about our FutureTalks series, make sure to join our Meetup group, New Relic FutureTalks PDX, and follow us on Twitter @newrelic for the latest developments and updates on upcoming events.
June 22, 2015
by Fredric Paul
· 1,656 Views · 1 Like
article thumbnail
Heroku PostgreSQL vs. Amazon RDS for PostgreSQL
Written by Barry Jones. PostgreSQL is becoming the relational database of choice for web development for a whole host of good reasons. That means that development teams have to make a decision on whether to host their own or use a database as a service provider. The two biggest players in the world of PostgreSQL are Heroku PostgreSQL and Amazon RDS for PostgreSQL. Today I’m going to compare both platforms. Heroku was the first big provider to make a push for PostgreSQL instead of MySQL for application development. They launched their Heroku PostgreSQL platform back in 2007. Amazon Web Services first announced their RDS for PostgreSQL service in November 2013 during the AWS re:Invent conference to an overwhelming ovation by the programmers in attendance. Pricing Comparison Before I get too far into the features, let’s cover the pricing differences up front. Of course, both services have areas with different value propositions for productivity and maintenance that go beyond these direct costs. However, it’s worth it to understand the basic costs so you can weigh those values against your needs later. Heroku PostgreSQL has the simplest pricing. The rates and what you get for them are very clearly set at a simple per-month rate that includes the database, storage, data transfer, I/O, backups, SLA, and any other features built into the pricing tier. With RDS for PostgreSQL, pricing is broken down into smaller units of individual resource usage. That means there are more factors involved in estimating the price, so it’s a little tougher to draw an exact comparison to Heroku PostgreSQL. You have the price per hour for the instance type, higher if it’s a multiple availability zone instance, cheaper if you pay an upfront cost to reserve the instance for one to three years; storage cost and storage class (both single and multi AZ); provisioned IOPs rate; backup storage, and data transfer… then there are a whole lot of special cases to consider. Also, keep in mind that you get one year free of the cheapest plan when you sign up. Here is a comparison of an RDS plan to the Heroku Premium 4 plan: Heroku Premium 4 $1,200 / Month 15 GB RAM 512 GB storage 500 connections High Availability Max 15 minutes downtime/month 1 week rollback Point in time recovery Encryption at rest Continuous protection (offsite Write-Ahead-Log) RDS for PostgreSQL $1,156/month on demand or $756/month 1 year reserved db.m3.xlarge Multi-AZ at $0.780/hr ($580) 4 vCPU, 15GB RAM Encryption at rest 512 GB provisioned (SSD) at $0.250/GB ($128) 2000 provisioned IOPS at $0.20/IOPS ($400) Estimated backup storage in excess of free for 1 week rollback, 512 GB at $0.095/GB ($48) Data transfer estimated at $0 for most use cases 22 minutes downtime/month (based on AWS RDS SLA 99.95% uptime) Now, here are the caveats with such a comparison: Heroku isn’t disclosing the number of CPUs associated with their plans. Heroku’s High Availability is equivalent to AWS RDS Multi-AZ. In both setups, a read replica is maintained in a different geographic region specifically for the purpose of automatic failover in the event of an outage. With Heroku, your storage is fully allocated, and you do not pay for IOPS. As such, we don’t know what the limits are for IOPS, but they are very high performance databases. I allocated the minimum IOPS that AWS would allow for 512 GB, which was 2,000. We could go as high as 5,000 IOPS which would increase the price by $600/month. The AWS RDS backups may cost nothing depending on how much of the provisioned storage is actually being used. Backup storage is free up to the level of provisioned storage, and backups are generally smaller, incremental, and do not include the significant space used by indexes. This estimate was based on the seven days of storage needed to allow for one week rollback. AWS RDS storage can be scaled up on the fly, so your specific needs for RAM versus storage could create a wildly different pricing pattern. This comparison is aiming to draw an equivalent. AWS only charges for data transfers out of your availability zone (not including multi-AZ transfers), so transfer rates will not apply in most cases. Clear as mud. Setup Complexity Heroku PostgreSQL setup is dead simple. Whenever you create a PostgreSQL project, a free dev plan is already created with it with a connection waiting. Upgrading the database simply gives you a new connection string with a set username, password, hostname, and database identifier that are all randomly generated by their system. The database connection must be secure but is accessible anywhere on the internet, including directly from your home computer. You can also choose whether to deploy it in the US East region or in the European region. RDS for PostgreSQL setup is slightly more involved; you must select the various options outlined in the pricing section, including the instance type, whether or not it should be Multi-AZ, whether to enable encryption at rest, type of storage, how much to provision, IOPs to provision (if any), backup retention period, whether or not to enable automatic minor version upgrades, selection of backup and maintenance windows, database identifier, name, port, master user and password, which availability zone you want it to be created in and the selection of your VPC group and subnet group, and your database configuration. Obviously, RDS gives you significantly more control over the details. Depending on your point of view, that could be good or bad. The database configuration, for example, has a set of defaults for each database version for each instance type. You can take these defaults and make modifications to them with your own custom settings and then save those as your own parameter group to assign to this and any future databases that you may choose to create. The initial setup time can be slightly more involved because of the various factors like VPC, subnet groups, and public accessibility. However, once these have been defined the first time for your account, everything gets much closer to a point-and-click experience. Host Locations, Regional Restrictions Heroku operates with the AWS US East Region (us-east-1) and Europe (eu-west-1). This also means that your database will be restricted to these regions. Availability Zones are managed internally. If you choose to use Heroku PostgreSQL with something hosted in a different AWS region than those two, you should expect more latency between database requests and transfer rates may apply. Likewise, if you wish to use AWS RDS for PostgreSQL with a Heroku application, just ensure that it is set up in the appropriate region. Security and Access Considerations Within Heroku PostgreSQL, you’re given a randomized username with a randomized password and a randomized database name that must be connected to over SSL. Their network (as well as Amazon’s) have built-in protections against scanners that could potentially brute-force access such a database. That is fairly secure. The downside is that anybody who needs access to the database and has the connection information can do so from anywhere in the world. This is more of a Human Resources-level risk from departed programmers on a project than anything else, but it is something to be aware of nonetheless. Swapping out the database credentials after having a programmer leave the team will generally alleviate this concern. On the other hand, AWS RDS for PostgreSQL has a much more comprehensive security policy. The ability to set and define a VPC and private subnet groups will allow you to restrict database access to only the servers and people who need it. You have the ability to create as many database users with various permission levels as you like in order to more easily manage multiple users or applications accessing the database with different permission levels, while providing a log trail. Thanks to VPC, even if somebody did have the connection information, they still couldn’t access the database without being able to get inside the VPC. For stricter (although more complex) security, RDS wins hands down. Depending on complexity, team, and the development state of your application, this level of security paranoia may not yet make sense and could be more of a headache than you want to manage. You can also configure it with the same access rules used by Heroku PostgreSQL. Backup/Restore/Upgrade Both platforms offer very similar options for backup and restore. Both have scheduled backups, point-in-time recovery, restoration to a new copy, and the ability to create snapshots. Upgrades are more involved. On both platforms, major version upgrades will involve some downtime, which can’t be avoided. Heroku provided three options that all involve some manual steps to complete: copying data, promoting an upgraded follower, or using the pg:upgrade command for an in-place upgrade of larger databases. The pg:upgrade most closely resembles the upgrade process on RDS. With RDS, you select the Modify option for your instance and change the version. It will create pre- and post-snapshots around the in-place upgrade while maintaining the exact same connection string. RDS will allow you to schedule the database upgrade automatically within your set maintenance window. Heroku PostgreSQL will automatically apply minor upgrades and security patches, while RDS allows you to choose whether or not you want them to do that automatically within your maintenance window. Both are fairly straightforward processes, although the RDS process is a little more hands-off in this case. Feature/Extension Availability As of this writing, AWS RDS for PostgreSQL has version 9.3.1–9.3.6 and 9.4.1, while Heroku PostgreSQL has 9.1, 9.2, 9.3, and 9.4. Minor version upgrades are automatic with Heroku, so the point releases are unnecessary. Heroku PostgreSQL has been around longer and because of that has more legacy versions available for their existing users. RDS launched with 9.3 and does not appear to have any intention to support older versions. In addition to all of the functionality built into PostgreSQL, there’s a constantly growing set of extensions. Both platforms have these extensions in common: hstore citext ltree isn cube dict_int unaccent PostGIS dblink earthdistance fuzzystrmatch intarray pg_stat_statements pgcrypto pg_trgm tablefunc uuid-ossp pgrowlocks btree_gist PL/pgSQL PL/Tcl PL/Perl PL/V8 Available on Heroku PostgreSQL: pgstattuple Available on AWS RDS for PostgreSQL: postgres_fdw chkpass intagg tsearch2 sslinfo Here are the full lists for both Heroku PostgreSQL and AWS RDS for PostgreSQL. Scaling Options “Scaling” is a tricky word with databases because it means different things depending on the needs of your application. Scaling for writes vs. reads is based on low intensity and high volume (web traffic) compared to low volume and high intensity (analytics). The most common scaling case on the web is scaling for read traffic. Both Heroku and RDS address this need with the ability to create read replicas. RDS calls them read replicas and Heroku calls them followers, but they’re essentially the same thing: a copy of the database, receiving live updates via the write-ahead-log over the wire to allow you to spread read traffic over multiple servers. This is commonly referred to as horizontal scaling. To create read replicas on either platform is a point-and-click operation. Vertical scaling refers to increasing or decreasing the power of the hardware of your database in place. AWS and Heroku each handle this scenario differently. Heroku instructs users to create a follower of the newly desired database class and then promote it to the primary database once it’s caught up, destroying the original afterwards. Your application will need to update its database connection information to use the new database. If your RDS database is a multi-AZ database, then the failover database will be upgraded first. Once ready, the connection will automatically failover to that instance while the primary is then upgraded, switching back to the primary afterwards. Without a Multi-AZ, you can do the upgrade in place, but downtime will vary depending on the size of the database. Your other option is to create a read replica with the newly desired stats and then promote it to primary when it is ready, just as Heroku recommends. To scale beyond the standard vertical and horizontal options for something that can handle distributed write scaling, neither option is a particularly good fit. It will probably be necessary to either manage your own Postgres-XC installation or restructure your application to isolate the write-heavy traffic into a more use-case specific data source. Monitoring AWS RDS for PostgreSQL comes with all of the standard AWS monitoring options via Cloudwatch. Cloudwatch provides extensive metrics that you can track history with a granular ability to set up alerts via email or SNS notifications (basically webhooks). These are great for integrating with tools like PagerDuty. Heroku PostgreSQL monitoring relies more on logs and command line tools. Their pgextras command line tool will show current information about what’s going on in the database, including bloat, blocking queries, cache and index hit ratios, identification of unused indexes, and the ability to kill specific queries. These tools, while not involving the stat tracking over time that you get from Cloudwatch, provide extremely valuable insights into what’s going on with your database that you don’t come close to getting from RDS. You can see more examples of pg-extras on GitHub. These type of insights are invaluable in tuning your application and database to avoid the problems you’d need a monitor to catch in the first place. Other historical data is available in the logs, although Heroku recommends trying out Librato (which can work with any PostgreSQL database but has a Heroku plugin available for automatic configuration). Additionally, free New Relic plans will provide a wealth of insight into what’s going on with your application and database. While Cloudwatch provides more detailed insight as to what’s going on within the machine, Heroku uses the metrics seen within pg-extras to monitor and notify you of the various problems they see that require correction on your end. If data corruption happens, Heroku identifies and fixes it. Security problems, they’ll handle it. A DBA or a DevOps position will care significantly more about the Cloudwatch metrics. Heroku PostgreSQL tries to focus on making sure you don’t have to worry about it. Dataclips One bonus feature that you get from Heroku PostgreSQL is Dataclips. Dataclips are basically a method for storing and sharing read-only queries among your team for the sake of reporting without having to grant access to every person who may need to see them. Just type in a query and view the results right there on the page. The queries are version controlled; if your team is passing them around and tweaking them, you’ll be able to see the changes over time. In my personal experience, I’ve found dataclips to be a lifesaver, specifically for working with non-programmer teams. When business or support staff need information on sales, fraud, user behavior, account activity, or anything else we happen to have in there, I’ve always had the ability to write up a query to get at the information. Before dataclips, this meant that I needed to write up the query, save it somewhere, usually export the result set to a CSV or spreadsheet, and then email it to whomever was requesting it. Eventually, this becomes a routine activity that you’re having to handle at every request. Enter dataclips. Now I can take that query and just send the random hashed link over to whoever requested the information. If they want more up-to-date information the next day, week, or month, they need only refresh the page. I write the query, then never hear that request again. That is a developer time-saver right there. You can save them and name them, as well as manage more strict access if need be. Summary and Recommendation Overall, AWS RDS for PostgreSQL will usually be cheaper and more tightly tailorable to exactly what your application’s needs are. You’ll have much more granular control over access, security, monitoring, alerts, geographic location, and maintenance plans. With Heroku PostgreSQL, you’ll pay a little bit more on a simplified pricing structure, although all of your development databases will be free. You won’t be able to control a lot of the details that RDS gives you access to, but that’s partially by design so that you don’t have to deal with managing those details. With Heroku, you’ll get insights directly into how your database is performing and using the internal resources to help you catch, tune, and improve your setup before it becomes a problem. If I had to choose, I’d probably go with Heroku and Heroku PostgreSQL as a startup while I focused on actually getting my application developed and getting customers in the door. The value proposition of saving time to focus on business goals so we can build a revenue stream would be of the greatest importance. Then when things grew to a point that the database was no longer changing as much, it might make sense to start migrating things over to RDS as we focus on locking things down to focus on stability, long-term maintenance, and security. In the end, it really boils down to what costs you more: time or infrastructure. If time costs you more, go with Heroku PostgreSQL. If infrastructure costs you more, go with RDS. Having both platforms living within the AWS datacenters makes switching between the two a lot easier as your needs change.
June 22, 2015
by Moritz Plassnig
· 3,950 Views
  • Previous
  • ...
  • 1465
  • 1466
  • 1467
  • 1468
  • 1469
  • 1470
  • 1471
  • 1472
  • 1473
  • 1474
  • ...
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×