It seems like every single plant, tree, or bush is budding and flowering in the Twin Cities of Minneapolis and St. Paul. The results are a large concentration of pollen which does not go well with people like my wife and me that have allergies. Not sure if it was the huge amount of snow we received last winter or … (fill in as you wish), but the weather is changing. Seems like some days our temperature is below average, but when you compare the highs and lows for the year with others, there seems to be a slight trend upwards. That might be the reason why plants are blooming and therefore making it hard for allergy sufferers.
In a series of posts regarding a sample DICOM web server, we have been working with JavaScript in order to come up with a server that eventually could be deployed using Docker or something similar. In this post I would like to briefly discuss the three alternatives I am considering for deployment. Note that once a service is deployed, we will have to support and maintain it with customers expecting the highest possible availability and reliability for their records and images. Based on this we have the following set of decisions to make as far as the cloud is concerned:
Build our own |
Use existing |
Hybrid |
When building our own cloud, we have to consider the initial costs for hardware and software. We also need to find a service provider in which to deploy our hardware unless we want to do it in our facilities. Once the system is up and running we need to periodically be able to provide updates. It used to be that updates were provided once or twice a year, but in today’s business climate, we need to use Continued Integration / Continued Deployment in order to keep up with competitors. This implies that in addition to the hardware and software in the cloud, we need to provide additional hardware and software to make sure our developers are able to support CI / CD. That also has an associated price tag.
Our DICOM storage will need to store for different time periods different types of images depending on the geographical location of our facility and clients. Keep in mind that some countries require that all user data cannot be stored outside their country. We also have to think about response time from when a client makes a request and the set of images is delivered to them.
In addition we must have the means to rebuild our databases and restore our DICOM images. This requires our solution to keep multiple copies of databases and files. That demands additional hardware and software which is able to maintain replicas.
We also must keep in mind that there will be ongoing needs of human resources to apply software patches and maintain / swap the hardware when (not if) it fails.
The last item that I would like to bring up is how are we going to decide on the amount of hardware and software to purchase upfront? We might not get enough and our customers will not be happy, or we will overspend and keep the hardware idle. In the latter we will get our management unhappy.
It seems like before building our own cloud, you should consider all the pros and cons for the selected approach. On the other end of the spectrum is using a cloud provider. They come in different sizes with similar yet different options. Depending on the number of customers and the requirements of the application, we could use different providers. I would consider Amazon, Google and Microsoft. Keep in mind, that in the upper echelon they all service to some degree all software platforms. If you are going with Docker, Swarm, Kubernetes, or another container approach, you should be happy with any of the players.
As you know I am constantly reading and watching videos in order to learn by experimentation. On paper all might look the same, but when you start trying different features you and your team of developer and DevOps engineers might favor a platform. For example, if your shop runs on Windows, you might put additional weight on Azure. If you run Linux, you might be more confident with AWS.
At this time I am experimenting with AWS. That said, in the future I will also experiment with Azure. I have developed a few products and services and I like to follow the KISS rule. This applies to all the steps needed to develop and maintain the service. A few weeks ago I watched one or two live webinars from Microsoft on Azure. They want to make it easy to use their offerings by wrapping standard tools and offering a unified front. I personally like to continue working directly with the tool because team members are already familiar with them. That said; one must always keep their options open in order to move to a different provider and switch tools as simpler and more powerful ones are introduced. Today many software development tools, toolkits, and frameworks are Free of the Shelf Software (FOSS).
We have started using MongoDB in our DICOM storage server. MongoDB is a NoSQL database. We will be using other databases to determine if they also fit our requirements. AWS has a database engine name DynamoDB. I have read a couple articles and I would like to give it a try. If you are interesting in learning more about it you can do it here and here. If you read the Amazon description you will be compelled to give it a try.
To be able to trigger a build and deployment when a commit on the software is performed, you can use tools like Jenkins, Puppet, and Chef among others. I will try to experiment with them in future posts and will see which ones are easier to use on AWS. Typically developers like to work in their sandbox and with little effort (if any) use the same tools on the cloud.
One more thing I did today was to update MongoDB on my Windows 10 machine. I was running MongoDB 3.6.* and decided to update to the latest version (4.0.9). To start I stopped the MongoDB service on my machine. I proceeded to download the latest installer and start it. I took all defaults. When done I noticed that the software had installed in a parallel path as illustrated by the following screen capture:
C:\>dir "C:\Program Files\MongoDB\Server" Volume in drive C is OS Volume Serial Number is 26E8-87B0 Directory of C:\Program Files\MongoDB\Server 05/06/2019 01:26 PM <DIR> . 05/06/2019 01:26 PM <DIR> .. 04/29/2018 10:53 AM <DIR> 3.6 <==== previous 05/06/2019 01:26 PM <DIR> 4.0 <==== new 0 File(s) 0 bytes 4 Dir(s) 576,661,311,488 bytes free
I then updated the following environment variable:
Path C:\Program Files\MongoDB\Server\4.0\bin
To get to the previous databases, I updated the following:
C:\>type "C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg" # mongod.conf # for documentation of all options, see: # http://docs.mongodb.org/manual/reference/configuration-options/ # Where and how to store data. storage: # dbPath: C:\Program Files\MongoDB\Server\4.0\data dbPath: c:\data\db <==== journal: enabled: true # engine: # mmapv1: # wiredTiger: # where to write logging data. systemLog: destination: file logAppend: true path: C:\Program Files\MongoDB\Server\4.0\log\mongod.log # network interfaces net: port: 27017 bindIp: 127.0.0.1 #processManagement: #security: #operationProfiling: #replication: #sharding: ## Enterprise-Only Options: #auditLog: #snmp:
By doing so I did not have to copy the databases to the location indicated by the new installation. The only thing missing was to start the MongoDB Server service. The software seems to have updated fine and I am able to get to the previous collections as illustrated by the following:
C:\>mongo MongoDB shell version v4.0.9 connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb Implicit session: session { "id" : UUID("30902d28-3cce-4e4e-a251-bb59ef602669") } MongoDB server version: 4.0.9 Server has startup warnings: 2019-05-06T13:40:57.383-0500 I CONTROL [initandlisten] 2019-05-06T13:40:57.383-0500 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2019-05-06T13:40:57.384-0500 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2019-05-06T13:40:57.384-0500 I CONTROL [initandlisten] --- Enable MongoDB's free cloud-based monitoring service, which will then receive and display metrics about your deployment (disk utilization, CPU, operation statistics, etc). The monitoring data will be available on a MongoDB website with a unique URL accessible to you and anyone you share the URL with. MongoDB may use this information to make product improvements and to suggest MongoDB products and deployment options to you. To enable free monitoring, run the following command: db.enableFreeMonitoring() To permanently disable this reminder, run the following command: db.disableFreeMonitoring() --- > show dbs admin 0.000GB agg 0.000GB blog 0.000GB chat 0.000GB config 0.000GB course 0.000GB dicom 0.000GB images 0.000GB local 0.000GB m101 0.000GB mongo-exercises 0.000GB school 0.000GB students 0.000GB test 0.041GB towns 0.000GB video 0.000GB > use images switched to db images > show collections images > db.images.find().pretty() { "_id" : ObjectId("5cc72293d56b582c60f63742"), "tags" : [ "chest", "lateral" ], "date" : ISODate("2019-04-29T16:13:07.326Z"), "reviewed" : false, "name" : "11111111111111111111111111111199", "patient" : "Money Penney", "width" : 128, "height" : 256, "__v" : 0 } { "_id" : ObjectId("5cc7227237c5612ba896038b"), "tags" : [ "chest", "lateral" ], "date" : ISODate("2019-04-29T16:12:34.832Z"), "reviewed" : false, "name" : "11111111111111111111111111111111", "patient" : "James Bond", "width" : 256, "height" : 256, "__v" : 0 } { "_id" : ObjectId("5cc757d77525e33e7816b803"), "tags" : [ "hand", "lateral" ], "date" : ISODate("2019-04-29T20:00:23.601Z"), "reviewed" : false, "name" : "12311111112222222222333333333399", "patient" : "John Canessa", "width" : 512, "height" : 512, "__v" : 0 } { "_id" : ObjectId("5cc72e2dcf67480dfc23aa1e"), "tags" : [ "hand", "lateral" ], "date" : ISODate("2019-04-29T17:02:37.311Z"), "reviewed" : false, "name" : "11111111112222222222333333333399", "patient" : "James Smith", "width" : 512, "height" : 512, "__v" : 0 } { "_id" : ObjectId("5cc75814f2e4d435f06cbee7"), "tags" : [ "right leg", "side" ], "date" : ISODate("2019-04-29T20:01:24.501Z"), "reviewed" : false, "name" : "12341111112222222222333333333399", "patient" : "John Smith", "width" : 512, "height" : 1024, "__v" : 0 } { "_id" : ObjectId("5cc72254a72d243298a2a16a"), "tags" : [ "right leg", "lateral" ], "date" : ISODate("2019-04-29T16:12:04.976Z"), "reviewed" : false, "name" : "11111111111111111111111111111111", "patient" : "John Doe", "width" : 256, "height" : 256, "__v" : 0 } { "_id" : ObjectId("5cc757f24b23593dc4f18107"), "tags" : [ "hand", "front" ], "date" : ISODate("2019-04-29T20:00:50.272Z"), "reviewed" : false, "name" : "12311111112222222222333333333399", "patient" : "Jane Smith", "width" : 256, "height" : 512, "__v" : 0 } { "_id" : ObjectId("5cc75789c4523c19504f7acd"), "tags" : [ "hand", "lateral" ], "date" : ISODate("2019-04-29T19:59:05.801Z"), "reviewed" : false, "name" : "12111111112222222222333333333399", "patient" : "John Canessa Smith", "width" : 512, "height" : 512, "__v" : 0 } { "_id" : ObjectId("5cc70683e6626c32b8ebb0b6"), "tags" : [ "right leg", "lateral" ], "date" : ISODate("2019-04-29T14:13:23.730Z"), "reviewed" : false, "name" : "11111111111111111111111111111111", "patient" : "John Doe", "__v" : 0 } { "_id" : ObjectId("5cc7586b62b47f2bfcefe820"), "tags" : [ "left arm", "side" ], "date" : ISODate("2019-04-29T20:02:51.324Z"), "reviewed" : false, "name" : "12345111112222222222333333333399", "patient" : "Jane Smith", "width" : 512, "height" : 1024, "__v" : 0 } { "_id" : ObjectId("5cc7589c66c6353d703ba985"), "tags" : [ "left arm", "side" ], "date" : ISODate("2019-04-29T20:03:40.890Z"), "reviewed" : false, "name" : "12345111112222222222333333333399", "patient" : "Jane Smith", "width" : 512, "height" : 1024, "__v" : 0 } { "_id" : ObjectId("5cc7583de26d8038f86588a6"), "tags" : [ "left arm", "side" ], "date" : ISODate("2019-04-29T20:02:05.573Z"), "reviewed" : false, "name" : "12345111112222222222333333333399", "patient" : "Jane Smith", "width" : 512, "height" : 1024, "__v" : 0 } { "_id" : ObjectId("5cc7585f285dd410a4131495"), "tags" : [ "left arm", "side" ], "date" : ISODate("2019-04-29T20:02:39.622Z"), "reviewed" : false, "name" : "12345111112222222222333333333399", "patient" : "Jane Smith", "width" : 512, "height" : 1024, "__v" : 0 } { "_id" : ObjectId("5ccd89fc3279f92e805bf853"), "tags" : [ "left hand", "top" ], "reviewed" : false, "name" : "11111111113333333333888888888800", "patient" : "Money Penny", "width" : 1024, "height" : 1024, "date" : ISODate("2019-05-04T12:47:56.760Z"), "__v" : 0 } { "_id" : ObjectId("5ccd929fd9ab284414522a74"), "tags" : [ "left hand", "top" ], "reviewed" : false, "name" : "88888888889999999999111111111177", "patient" : "Gray Skull", "width" : 1024, "height" : 1024, "date" : ISODate("2019-05-04T13:24:47.020Z"), "__v" : 0 } { "_id" : ObjectId("5ccd955c20cdc735d07af611"), "tags" : [ "left hand", "finger" ], "reviewed" : false, "name" : "11111111114444444444333333333371", "patient" : "Gold Finger", "gender" : "Male", "width" : 512, "height" : 512, "date" : ISODate("2019-05-04T13:36:28.333Z"), "__v" : 0 } { "_id" : ObjectId("5ccd9809973d634be8df31d9"), "tags" : [ "head", "frontal" ], "reviewed" : false, "name" : "11111111112222222222000000000099", "patient" : "Hugo Drax", "gender" : "Male", "width" : 512, "height" : 9999, "date" : ISODate("2019-05-04T13:47:53.867Z"), "__v" : 0 } { "_id" : ObjectId("5ccecb580673f40a54cf9a5b"), "tags" : [ "left foot" ], "reviewed" : false, "name" : "12345678909999999999222222222288", "patient" : "Rosa Klebb", "gender" : "Female", "width" : 256, "height" : 2048, "date" : ISODate("2019-05-05T11:39:04.080Z"), "__v" : 0 } >
If you have comments or questions regarding this or any other post in this blog, or if you would like me to help with any phase in the SDLC (Software Development Life Cycle) of a product or service, please do not hesitate and leave me a note below. Requests for help will remain private.
Keep on reading and experimenting. It is the best way to learn!
John
Follow me on Twitter: @john_canessa