Yes Virginia, your database is working too hard
Over the last few days, I've been noticing that the MySQL instance for DZone had been working ever harder. Many of you have followed the adventures of Rick and Matt through the dark art that is SQL and databases, and this latest problem had all the earmarks of some bad queries. As I began to dig into the problem a bit more, I began to suspect that something wasn't using the caching subsystem that I've written about in the past. The whole reason I reworked much of the database system to implement caching at DZone was that many of the queries we had initially written were bloated and inefficient, doing unnecessary joins, and just selecting entirely too many columns in general. As I looked through the connections that were operating at DZone at any given time, I began to see a pattern. With the excellent tool, Navicat, I began to see that there were quite a lot of queries creating temporary tables and which appeared to be using pieces of the queries I thought I had replaced throughout most of this part of the system. As it turned out, it was a query that did entirely too much work to return such a simple result AND it wasn't taking advantage of the new caching system. With a simple switch of the queries and a quick deploy, the long-term load on the machine was cut in half. Not a bad improvement for about 30 minutes of work. Over the past year of DZone, we've always been of the mind to build now, optimize later. The problem with that mode of operation is that you have to be just a little insane about knowing how your system normally performs and about keeping stats on how your system runs. We constantly keep an eye on how the system is performing. I almost feel like I have a connection with the server and I know when it's not feeling well. You have to know that you can eek out that extra performance without taking the sledgehammer to your code. We know our code isn't perfect and we have made it so we can make quick changes, see how things perform, and then make some more changes. It's a mode that works for us and has helped us do more with less. Making Java just a bit more dynamic
Over the weekend, Rick and I starting to hatch a nefarious plan to take over the Internet. Wait, no that was last weekend! This weekend, we began to gather our initial thoughts on a super flexible way to manage custom objects here at DZone. The main problem we ran into was the fact that Java isn't dynamic. It really made me appreciate the fact that you can do things like add methods to existing classes on the fly in Ruby, but I digress. As I soon found out, Java doesn't have to be quite so strict. After digging through Google for a while, I began to find out that we weren't the only ones who wanted things to be a bit more flexible. Groovy, while not necessarily Java, lets you override a class and add methods or properties to it. That would have been awesome, except I needed to return a real Java class instead of something in Groovy. With a little more digging, I found an interesting article on developerWorks about using proxies and reflection to route calls to getter and setter methods to a dynamically populated HashMap. Now I was getting somewhere. I could use something like this to handle calls to methods that didn't exist and route them to fields that might have been loaded from the database. Encouraged by my finds, I dug even deeper into this mysterious world of dynamic decorators and dynamic proxies. Reflection and Introspection are some powerful features of Java, and I was determined to leverage them to my advantage here. Finally, I found something that looked to be a potential Holy Grail, Janino. From what I can tell, with Janino I can build up a String of my dynamic extension to a base class and have it compiled on the fly and inserted into the ClassLoader. For my purposes, I only need the class generated at the end of certain actions, not constantly, so Janino might just work. The main issue I can see right now, is how I am going to deal with server restarts. I guess when the server starts I'll need to determine what extensions I need and compile those into the classloader. The documentation seems to say that things are compiled right into the classloader you specify, so I can build up a String in memory that defines a Bar that adds some completely new properties to a Foo and then use the Bar in whatever I want. Very cool! The few hours I spent investigating this on Sunday evening really started to push the limits of what I understood about Java - reaching out to the gray areas of what I thought should be possible. I was happy to see that fortunately other people had already walked some of these roads before. Have any of you worked with dynamic proxies to support a type of dynamic java bean? Maybe something to implement a call to properties bag when you call a method that doesn't exist? Let me know and be sure to let me know about any experience you might have with Janino! Until Next Time,
Matthew Schmidt
matt@javalobby.org
Yahoo IM: mattschmidtjl |