CPU Overprovisioning and VMWare

So I did find out that when you assign a VM vCPUs in ESXi you have to consider queuing. Consider if you have a host with 8 threads and give a VM 8 and then another VM a single one. If that VM with one vCPU is running at 100% that VM with 8 is going to have to wait for all 8 to become available at the same time. VMWare will eventually split the time but it is still a huge performance impact. They say 3 physical cores to vCPUs is a good ratio to maintain and the more physical cores the better.

Neat paper on VMWare overprovisioning

I recently came across a neat article on VMWare over provisioning and what are considered best practices. Something I always thought was that as long as CPUs are in use on the host you can keep handing out vCPUs. It appears that you start reaching points where the hypervisor needs to queue up workloads so the VMs end up waiting for a CPU to become available. One thing I wonder though is for multi core VMs. If a VM has 8 vCPUs does it have to wait for 8 threads to become available at the same time or can VMWare provide partials until it has more? Here’s the paper:

[pdf-embedder url=”https://serverhobbyist.com/wp-content/uploads/2018/10/Dell-Best-Practices-for-Oversubscription-of-CPU-Memory-and-Storage-in-vSphere-Virtual-Environments_0.pdf” title=”Dell Best Practices for Oversubscription of CPU Memory and Storage in vSphere Virtual Environments_0″]

Server Hardware

A few years ago I bought a Dell R610 to add to my fleet of servers. It did alright but I had always dreamed of having better storage. I found a Dell Direct Attached Storage array on eBay for cheap. It had some mismatched drives but they were all the same size and it seemed to run. I bought the external RAID card for the R610 and hooked it up. I loaded VMWare ESXi 6.0 on the server and it immediately saw the storage. I had some questions about RAID on the array but settled on a RAID 5 across all the disks. Between the 512 MB cache on the card and spanning all of the 10k RPM SAS disks it is fast. It is much more difficult to bottleneck the disks. I learned a couple good lessons from this. That many disks running in your basement will function as a space heater. More importantly I learned the importance of a good RAID controller. Having that cache really helps prevent the disks from getting bogged down when multiple VMs try to read or write to the disks.

Learning about NodeJS, ExpressJS, and other components of server side javascript

Recently I’ve been learning about NodeJS and how to write server side JavaScript. This week I was creating a route that pulled variables fromĀ  POST, inserted them into a SQL database, and then retrieved the ID of the inserted record. Later on I wanted to take that ID and retrieve the record submitted. When the code ran I didn’t have errors but I had symptoms that didn’t make sense. As my debugging strategy I started logging variables to make sure they had values that I expected.

sqlInsertServer = "INSERT INTO serverbuilddata (ServerName, CPUCount, RAMCount) VALUES ('" + serverName + "'," + CPUCount + "," + serverMemory + ');'
console.log('SQL Statement: ' + sqlInsertServer);
var buildID;
con.query(sqlInsertServer, function (err, result) {
if (err) throw(err, null);
buildID = result.insertId;
console.log("Inside function. Server record inserted. Build ID: " + buildID);
);
console.log(buildID);

The first instance of build ID I logged inside the function returned the correct result, but the one outside of the function was undefined. I thought it was a scoping problem at first and tried to make sure the variable was declared globally. Then I noticed that the undefined variable outside the function was being logged before the one in the function. Then it kind of clicked about how Node is asynchronous. It doesn’t wait for other functions to run before the code gets executed even if they are in the correct order. After some research about my options I decided to go with call backs since they seemed to be the most recommended and best way.

sqlInsertServer = "INSERT INTO serverbuilddata (ServerName, CPUCount, RAMCount) VALUES ('" + serverName + "'," + CPUCount + "," + serverMemory + ');'
console.log('SQL Statement: ' + sqlInsertServer);

function serverInsert(callback) {
var buildID;
con.query(sqlInsertServer, function (err, result) {
if (err) callback(err, null);
buildID = result.insertId;
callback(null, buildID);
console.log("Inside function. Server record inserted. Build ID: " + buildID);
});
}

serverInsert(function (err, buildID) {
if (err) {
// error handling code goes here
console.log("ERROR : " + err);
} else {
// code to execute on data retrieval
console.log("result from callback is : " + buildID);
})

Callbacks wait for the function to provide it with a value. The problem is that value still can’t be used outside the function. And if that value in the callback needs to be used in another SQL function you need to nest another callback in the callback. Before you know it you have a mess. It does work but I’m still looking for better ways to do it. I’ve read about promises but I’m not ready for that yet.