8 Replies Latest reply on Aug 22, 2006 1:33 PM by manik

    Blob balancer using cache - concept help

    zambak

      Hi

      I was wondering if someone can help me decide if I can use JBoss Cache to solve following problem:

      We have a webapp that will be installed on 2 servers which in turn will be load balanced using Cisco content switch. Web application has a user part which is to show a lot of images and an admin part which has capability to upload images.

      The problem is that right now images are just files on a disk so when upload occurs I have to figure out how to "copy" the uploaded file onto another server.

      What I would like to do is to store the uploaded image into a DB as a BLOB and then use cache to propagate it to other server. The problem is that I don't want user end of the app to load images from the DB but to somehow tell cache to recreate file on the disk and access it as a regular image...


      So the webapp would run on 2 servers and would share a DB. On the admin side, no matter on which server the file gets uploaded to it will be inserted into DB. On the user side, cache will write the file from the DB to the disk and user part of the app will just hadle it as a regular image file.


      I read JBoss Cache arhitecture and I understand I can persist the cache in the DB so it will survive server restarts. But can i tell JBOss cache to cache to the disk?

      Is there a way.....I hope I explained the situation well...

      Please help

      Z....

        • 1. Re: Blob balancer using cache - concept help
          brian.stansberry

          When you say the "user part of the app will just hadle it as a regular image file" do you mean the web container will serve it as an image?

          A possibility that comes to mind is to use a chaining cache loader, with unshared FileCacheLoader in front of a shared JDBCCacheLoader. The FileCacheLoader is configured to write its files to a place the web container will read. One the user server, the JDBCCacheLoader has

          <ignoreModifications>true</ignoreModifications>


          in its config, so when a change replicates from the admin server, it doesn't get rewritten to the DB.

          • 2. Re: Blob balancer using cache - concept help
            zambak

             

            "bstansberry@jboss.com" wrote:
            When you say the "user part of the app will just hadle it as a regular image file" do you mean the web container will serve it as an image?


            Exactly...What I want is something similar OSCache and EHcache have by the use of the servlet filter. Same app "sits" on 2 servers. After an image has been uploaded via admin part it is stored in the DB...I then want the JBoss Cache (somehow) to reproduce the image from the DB on both servers....Is this possible using solution you mentioned below?




            • 3. Re: Blob balancer using cache - concept help
              brian.stansberry

              IIRC, the OSCache and ESCache filters actually serve the image from the in-memory cached data. (I could be wrong; it's been a while.) You could do the same, and eliminate the FileCacheLoader.

              Serving files is surprisingly non-trivial though, so letting Tomcat do it by putting the file on the filesystem has advantages. What I described *could* work, I haven't tried something like it.

              The kind of funky thing about it is you're not really using the in-memory portion of the cache -- the webserver serves file from disk and the real store is the db. JBC is just being used to replicate the file from one server to another so the filesystem image is up to date.

              • 4. Re: Blob balancer using cache - concept help

                Mayby you could evict/remove the image (or some kind of ImageInfo-object) from the cache when a new image is uploaded or updated and then use a TreeCache interceptor that triggers the recreation of the image on disk on each instance.

                But I wouldn't store the actual image (the byte array) in the TreeCache, intead a pointer of some kind. Replicating a large image over the TreeCache/JGroups cluster could be slow depending on you config... We have a cluster with 8 servers and have had some performance problems with large objects.



                • 5. Re: Blob balancer using cache - concept help
                  manik

                  Using the file cache loader in this manner will not work, since the file cache loader serialises the attribute map of the node into a single file. Your webserver will not be able to parse and serve up this file.

                  Perhaps this approach may help:

                  1) Single, JDBC based cache loader
                  2) Uploading an image will result in the servlet converting the file to a byte[] and putting this in cache (so it gets stored in the db)
                  3) Register a cache listener on the cache, which when a node is created, your cache listener writes the byte[] to your filesystem in a specified place, in the file format specified.
                  4) Since the cache will replicate it's contents, this will trigger cache listeners on each instance in your cluster, so the file is created on the filesystems on each cluster node.

                  • 6. Re: Blob balancer using cache - concept help
                    brian.stansberry

                    Doh! Of course FileCacheLoader wouldn't work; don't know what I was thinking :( Sorry, zambak, for the noise; thanks, Manik, so saving me with a better solution.

                    carlabramsson's point about the advantage of replicating a pointer to a shared file rather than the image itself is a good one. Makes using the webserver to serve the file a bit trickier though.

                    • 7. Re: Blob balancer using cache - concept help
                      zambak

                       

                      "manik.surtani@jboss.com" wrote:
                      Using the file cache loader in this manner will not work, since the file cache loader serialises the attribute map of the node into a single file. Your webserver will not be able to parse and serve up this file.

                      Perhaps this approach may help:

                      1) Single, JDBC based cache loader
                      2) Uploading an image will result in the servlet converting the file to a byte[] and putting this in cache (so it gets stored in the db)
                      3) Register a cache listener on the cache, which when a node is created, your cache listener writes the byte[] to your filesystem in a specified place, in the file format specified.
                      4) Since the cache will replicate it's contents, this will trigger cache listeners on each instance in your cluster, so the file is created on the filesystems on each cluster node.


                      Thanks for the info. I will try this approach.
                      Some concerns though....

                      1) Since image will be uploaded and stored in the DB via admin part, can I use the same BLOB column when I configure JDBC based cache loader. I mean are the BLOBs compatible (as in case with File cache loader the map is serialized so image file and cached file are not the same, is it same true for JDBC loader?) If they are not compatible, then I am going to have to waste some DB space (duplicate BLOBS in DB one BLOB is app specific, one is for cache right?)....

                      2) In order to evict an item when a new image with a same name is uploaded (an update) will I need to have a listener perform this action logic?

                      If I understand this correctly, the listener would add/remove/update blobs in the cache every time admin action adds/removes/updates an image. Then we rely on cache achitecture to propagate same behavior across the cluster.

                      So we have add/update/remove image (in admin)

                      1) store/restore/reupdate image as a BLOB in DB (depending on concern outlined in #1)
                      2) add image as byte[] to cache
                      3) action in #2 will notify the listeners on all nodes and recreate/remove image from byte[] onto a disk




                      • 8. Re: Blob balancer using cache - concept help
                        manik

                         

                        "zambak" wrote:


                        1) Since image will be uploaded and stored in the DB via admin part, can I use the same BLOB column when I configure JDBC based cache loader. I mean are the BLOBs compatible (as in case with File cache loader the map is serialized so image file and cached file are not the same, is it same true for JDBC loader?) If they are not compatible, then I am going to have to waste some DB space (duplicate BLOBS in DB one BLOB is app specific, one is for cache right?)....



                        This is irrelevant since you will always be using the cache to read or write the contents of that blob. The reason it was a problem with the File Cache Loader was that you were trying to serve up the file directly using your webserver.

                        "zambak" wrote:

                        2) In order to evict an item when a new image with a same name is uploaded (an update) will I need to have a listener perform this action logic?

                        If I understand this correctly, the listener would add/remove/update blobs in the cache every time admin action adds/removes/updates an image. Then we rely on cache achitecture to propagate same behavior across the cluster.

                        So we have add/update/remove image (in admin)

                        1) store/restore/reupdate image as a BLOB in DB (depending on concern outlined in #1)
                        2) add image as byte[] to cache
                        3) action in #2 will notify the listeners on all nodes and recreate/remove image from byte[] onto a disk


                        Your admin tool (I presume this to be a servlet or JSP) would add/remove/update the image in the CACHE only (as a byte[]). Not directly in the DB. The cache will make sure this is persisted to the DB if you have a JdbcCacheLoader configured.

                        A cache listener - registered with the cache - will be responsible for creating a file on the filesystem, with the name and byte[] in the cache.

                        The cache listener should do this whenever the cache is modified or created.