Tag: SRE

  • Five Great DevOps Job Opportunities

    Five Great DevOps Job Opportunities

    devopsy.kinsta.cloud is now providing a weekly DevOps jobs report through which opportunities for DevOps professionals will be highlighted as part of an effort to better serve our audience.

    Our goal in these challenging economic times is to make it easier for DevOps professionals to advance their careers. Of course, the pool of available DevOps talent is still relatively constrained, so when one DevOps professional takes on a new role it tends to create an opportunity for others.

    The five job postings shared this week are selected based on the company looking to hire, the vertical industry segment and, naturally, the pay scale being offered.

    We’re also committed to providing additional insights into the state of the DevOps job market. In the meantime, for your consideration:

    LinkedIn

    Apple
    San Diego, California
    Site Reliability Engineer (SRE) – Video
    $115,000 to $217,500

    SimplyHired

    ScientiaMobile
    Reston, Virginia
    Senior DevOps Engineer
    $110,000 to $150,000

    Monster.com

    Larsen & Toubro Infotech Ltd.
    Farmington, Connecticut
    DevOps Engineer
    $110,000 to $130,000

    Indeed.com

    TherapyNotes.com
    Remote
    Senior DevOps Engineer
    $105,000 to $155,000

    Dice.com

    MRoads
    Dallas, Texas
    Platform Engineer – SRE
    $100,000 to $120,000

  • How To Build Anti-Fragile Software Ecosystems

    How To Build Anti-Fragile Software Ecosystems

    Just as organisms are susceptible to diseases and viruses, software systems are susceptible to hacks and errors. And within many complex interconnected systems, a minor bug could have a cascading effect across an entire organism, causing it to break. As such, increasing the resiliency of a software ecosystem is something engineers continually strive for. But how do we get there?

    One concept to consider is anti-fragile. Being anti-fragile refers to the ability of a system to thrive in adversity and adapt to change. Specifically, with regard to software, anti-fragile can equate to responsive coding practices, such as auto-scaling or default backups, to mitigate unforeseen events. Chaos engineering, for example, is one method to expose edge cases and build with adaptability in mind. And with the introduction of intelligent automation, often fueled by machine learning (ML) and artificial intelligence (AI), it’s becoming more and more feasible to build anti-fragile software systems.

    I recently met with Asim Razzaq, co-founder and CEO of Yotascale and former head of platform engineering at PayPal, to discover what it takes to build anti-fragile software. According to Razzaq, anti-fragile represents the next evolution of reactive, resilient software systems. And introducing anti-fragile concepts into your application networks can be done with just a few (relatively) simple steps. Below, we’ll define what anti-fragile is and see how this concept can be applied to software development and DevOps.

    Understanding Anti-Fragile

    As the adage goes, “What doesn’t kill you makes you stronger.” And it’s true—many natural systems tend to thrive under inhospitable conditions. As described by Nassim Nicholas Taleb in the book ‘Antifragile: Things That Gain from Disorder,’ anti-fragile systems thrive in adversity. For example, consider how human muscle grows under stress and load. Immune systems similarly adapt and respond to new viruses and improve the body’s resilience over time. So, how does this relate to software development?

    Well, organizations need to develop highly-tolerant software systems to meet rising digital consumer expectations. Especially when under extreme loads, systems must be elastic to adapt and survive. To meet high user demands, as well as specific service-level objectives (SLOs) and agreements (SLAs), most software companies are already investing in cloud-native tools that improve reliability. For example, a hallmark of site reliability engineering (SRE) is introducing automation to enhance the stability of applications.

    One example of gauging anti-fragile in software environments is chaos engineering, says Razzaq. Chaos engineering is the act of throwing a wrench into the machine. You randomly introduce bugs and malformed requests and attempt to create as much havoc as possible to see what happens. This could mean pulling out cables and restarting servers to gauge how software systems respond.

    “Software that can respond the best adapts the best,” said Razzaq. For example, if you manually remove a few nodes from the cluster but the system knows it needs seven to function, it could automatically spin up additional nodes. Or if the whole cluster goes down, ideally, the system would automatically restart and scale to the necessary requirements. In essence, anti-fragile software systems can understand and adapt to new environments without much, or any, human input.

    Tips to Construct Anti-Fragile Software Systems

    So, how can we construct anti-fragile software systems — especially when real-world challenges are often unpredictable? Razzaq shared helpful advice to consider when crafting anti-fragile software architecture.

    1. Start With Your Most Critical Systems First

    First, introduce chaos engineering to your most absolute critical systems. Define these vital components at the heart of your product which must remain functional. For a payments processor SaaS, for example, this would be the infrastructure supporting its transactional engine, such as the login and payment microservices.

    2. Determine How to Test Fragility

    Once you’ve identified this critical infrastructure, figure out how to test for fragility in your environment. Introduce chaos engineering to the component to see how it behaves. For example, returning to our payment platform example, this may include switching off a payment transaction type to see how the system functions in an extreme scenario.

    3. Decouple Components

    If systems are too closely coupled, errors and outages can ripple across multiple software services. To avoid that, it’s a good practice to prevent tight coupling between components—especially between critical systems and non-critical ones.

    4. Introduce Alternate Paths

    One method to decouple is by introducing alternate paths. For example, if a credit card verification component goes offline, the system should naturally accept other forms of payment and automatically suggest another form, such as a bank transfer. If all systems are down, the system could still accept unverified payments in a queue and let this continue until the threshold reaches a certain risk level.

    5. Learn From Past Events

    The next frontier of designing anti-fragile architecture is developing self-learning, autonomous systems. Of course, there is a limit to how automation can respond to unforeseen issues. But by feeding a machine learning model with more and more experiences, it could deal with untested new scenarios more gracefully. Of course, AI has the potential to make harmful decisions and even introduce unintentional bias, so organizations should have accountability for the algorithms they oversee, cautioned Razzaq.

    Benefits of Building With Anti-Fragile in Mind

    The goal is to able to thrive and function even under duress. By identifying the elements of core infrastructure to keep alive and putting it through the wringer, you can discover frailties before they cause significant consequences. And by decoupling components and introducing alternate paths, software systems can be better equipped for whatever may come. Uplevelling system operations with increased automation and AI is likely the future of constructing more fault-tolerant applications.

    “Software is everything in this day and age,” said Razzaq. “It increasingly plays a critical role in life-enhancing capabilities.” As such, the end benefits of developing an anti-fragile style could have hugely positive effects. In health care situations, it could make a difference in saving lives. For other less dire scenarios, increased fault tolerance leads to less lost revenue during peak traffic times and more consistent end-user experiences.

  • Why SREs Are Critical to DevOps

    Why SREs Are Critical to DevOps

    Although a relatively new concept, site reliability engineers (SREs) have become crucial for DevOps teams, helping to solve an array of operational problems such as network availability and user experience. However, in previous years, some people have questioned the longevity of such a role. 

    This article will discuss several reasons why site reliability engineering roles are here to stay and why they have become critical to DevOps. 

    What Are Site Reliability Engineers (SREs)?

    A site reliability engineer helps connect development teams and IT operations by completing tasks previously assigned to operational roles. SREs use a range of automation tools for troubleshooting purposes, creating software systems that are both scalable and reliable.

    The role revolves around automation and standardization, as cloud systems become increasingly prevalent. SREs also play a vital role in ensuring the user experience of systems is of the highest standard.

    Why Site Reliability Engineering Roles Are Here to Stay

    Let’s take a look at two of the primary reasons SRE roles are here to stay. 

    User Expectations

    The key reason for the rise in popularity and the expected longevity of site reliability engineering roles is user experience. In the modern climate, user expectations are very high and more dedicated roles are required to help deliver a service that is not only acceptable but attempts to exceed user expectations.

    Even back in the 2010s, users were much more patient in terms of website load speeds and how quickly they could access information. Even crashes and load failures were tolerated without the user exiting a website.

    However, that has all changed due to the competitiveness of the market, as well as the growth of remote working, which has increased dependency on online resources. This means that if a service is unavailable for any period, users are unable to do their job. 

    An SRE’s role includes optimizing systems, ensuring they perform at the required level and that resources are always available to those that need them. This makes SREs critical to DevOps teams that may not have the capacity to focus on meeting user expectations sufficiently. 

    The Complexity of Software Architectures

    Another factor that has added a lot of value to the role of an SRE is their ability to provide much-needed support for software environments and architectures that continue to develop in terms of complexity. Kubernetes is one such architecture that requires dedicated attention. 

    Applications that are distributed across systems such as Kubernetes and other cloud-native platforms require specialized personnel that have the necessary knowledge and experience. Machine learning is also becoming more prevalent and requires special focus from a performance perspective. In 2020, just more than 22% of companies had machine learning models in production for one to two years.

    This level of complexity is only expected to grow further over the coming years as cloud-native systems become the norm. This is why new roles must be created that go beyond that of a normal IT engineer. 

    Challenges for SRE Roles

    Like any IT role, the role of a site reliability engineer always faces challenges that have led people to question whether SREs are a long-term solution or whether it is a niche specialization. 

    A Lack Of Opportunity Away From Hyperscale Companies

    The role of an SRE was created by hyperscale companies like Google that manage extremely large IT systems. For companies that do not have such a wide and varied IT infrastructure on a global scale, there are questions about whether such a role is necessary. 

    However, as previously mentioned, the growth of cloud-native technology shows no sign of slowing and, with this growth, opportunities for SREs at smaller organizations may arise. 

    The Role of an SRE is Considered Obscure

    The ambiguity of an SRE role can be considered a downfall in some cases, with many businesses unsure of what these professionals offer when compared to a traditional systems engineer. In many cases, SREs are deemed to be a hybrid of a software engineer and an IT operations role. 

    Fortunately, DevOps has realized the potential of SREs and their ability to provide an important bridge between developers and engineers, helping to achieve dedicated tasks to a high standard. 

    SREs Vs. DevOps

    Although both roles are connected and share some similarities, there are some clear differences.

    • Processes – DevOps has full visibility into the development environment which allows them to make changes from the initial development stages through to production. SREs, on the other hand, only have visibility into the production process, allowing them to make suggestions to ensure performance levels are maintained.
    • Implementation – The task of implementing new features on a system falls on the DevOps team. Meanwhile, SREs are tasked with ensuring the new features do not cause any system failures or impact performance during the production stage.
    • Key Focus – The primary focus of a site reliability engineer is to ensure the system’s reliability, availability and scalability. DevOps focuses on how quickly product development is completed, as well as its continuity.
    • Structure – The structure of an SRE team and a DevOps team have obvious differences. SRE teams are made up of individuals who have similar skill sets relating to development and operations. Whereas DevOps teams consist of professionals who have specific roles related to individual aspects of the project. These roles can include the team leader, product owner, cloud architect, software developer, QA engineer, system administrator, release manager and more.
    • Tools – DevOps teams often use tools such as integrated development environments (IDEs) when developing a product. These can include Jenkins (continuous integration and continuous development), JIRA (change management), Splunk (log monitoring) and GitHub (distributed version control). SREs commonly use tools such as Prometheus and Grafana (collection and visualization of metrics, such as CPU usage and available disk space), OP5 and PagerDuty (incident alerts), Ansible and Kubernetes (container orchestration) as well as a range of cloud platforms.
    • Bug Reporting – DevOps debug code whenever a bug is reported in the end product. SREs are not involved with debugging from a development perspective and are only required to perform such tasks if there is a production outage, there are infrastructure issues or perhaps if they are dealing with common AWS misconfigurations.
    • Measuring Performance – The typical metrics that DevOps uses to measure performance are deployment frequency and deployment failure rate. SREs measure service level objectives (SLOs), service level indicators (SLIs), service level agreements (SLAs) and error budgets.
    • Incident Handling – In the case of incident handling, DevOps teams work to mitigate an issue based on the feedback provided. SREs then analyze the issues post-incident, including the root cause of the issue. This is then documented and provided to the developers to fix. 

    Why SRE Roles Are Critical to DevOps – Conclusion

    As you can see, the two roles differ significantly but SREs can play a critical role in ensuring the DevOps team delivers a product that offers maximum performance. 

    The core benefits of employing professionals in a site reliability engineer capacity are high levels of product performance and reliability to meet user expectations while helping to manage complex IT architecture. 

    In the future, organizations that manage a large amount of cloud-based IT assets may struggle to deliver efficient products without such professionals. As such, demand for SRE roles is likely to grow. 

  • Best of 2022: Day in the Life of a Site Reliability Engineer (SRE)

    Best of 2022: Day in the Life of a Site Reliability Engineer (SRE)

    As we close out 2022, we at devopsy.kinsta.cloud wanted to highlight the most popular articles of the year. Following is the latest in our series of the Best of 2022.

    By now, most of us are familiar with the concept of site reliability engineering (SRE). The term was originally coined by Google and SRE has been gaining traction in recent years as a role dedicated to increasing the resilience of digital ecosystems. To accomplish this, a big part of the SRE doctrine is “automating your job away.”

    Observability and monitoring tools are extremely important to DevOps and for SRE. But what is the day-to-day experience actually like for your average SRE? What activities does an SRE do? And what percentage of their time does an SRE spend on particular tasks?

    I recently met with James Curtis, lead site reliability engineer at a large multinational company. According to Curtis, the SRE approach takes a certain type of person—someone with Ops in their blood and a passion for eradicating repetitive tasks. Below, we’ll use his input and the input from other sources to better understand what it’s like being in the shoes of an SRE.

    Understanding the SRE Role

    Organizations have interpreted the role in different ways. But in a general sense, SREs attempt to maintain high reliability and availability for software applications and respond to incidents as they occur. To aid their efforts, an SRE tries to streamline and automate as many operations as possible to remove opportunities for human error.

    A hallmark SRE goal is to reduce “toil.” Curtis defines toil as “tedious actions that really have no enduring value.” For example, say an admin must manually restart a service in Microsoft Exchange every time a triggering event interrupts the service—this action could certainly be automated away. SREs spend much of their time eliminating toil by coding automation and configuring internal tools to better interact with software infrastructure.

    SREs usually are also in charge of logs and setting benchmarks using a tool like Splunk or Datadog to observe and ingest data. Curtis himself uses Cribl, which offers an observability pipeline to parse and route log data. Since SREs oversee internal service-level indicators, they are typically in charge of normalizing behavior and setting SLOs and SLAs.

    Common SRE Activities

    An SRE juggles a lot of tasks. For proof, read the hour-by-hour day in the life by Yonatan Schultz, SRE at New Relic. Schultz’s average day is spent configuring infrastructure, jumping from project to project, and, of course, hopping into many meetings. Here are some other tasks an SRE might perform on a daily basis:

    Monitoring service-level indicators (SLIs). An SLI could be the number of successful requests out of total requests. Having a high SLI, in this case, would be a target. SREs track other metrics such as availability, uptime performance, latency, error count and throughput. Regularly monitoring systems is essential to ensure proper resource utilization of containers and to avoid out-of-memory (OOM) errors.

    Setting SLOs and SLAs and determining error budgets. Once you have determined baseline system performance, you can set service-level objectives (SLOs). These are typically internal targets like 99.99% availability. While SREs typically oversee functional metrics, some teams set goals for non-functional metrics, as well. SREs help determine service-level agreements (SLAs), which are more legally binding and typically partner-facing.

    Responding to incidents. On-call SREs will be tasked with finding the root cause of issues as they arise. When triaging an incident, it’s helpful to have all the necessary logs and tools immediately at hand. This is one area where automation can assist by pulling relevant details to instantly build a case, said Curtis.

    Writing postmortems. After an incident has been dealt with, it’s important to learn from it. Postmortems are common in cybersecurity practice and often fall under the responsibility of an SRE. These reviews seek to answer set criteria to get to the heart of an incident and identify the root cause(s) of an issue to prevent it from happening again.

    Automating other system tasks. SREs will spend significant time coding and building tools for engineers to interact with infrastructure. For instance, an SRE might generate reliability reports that consider performance over long time periods.

    Cross-department collaboration. SREs don’t tend to own application code. Instead, they support multiple software divisions. This means checking in with other developers, disseminating best practices and reviewing new architectures to represent the reliability side of the equation.

    As you can see above, the SRE role might blend many different activities, and keeping track of them all may be part of the job itself. Anika Mukherji, an SRE at Pinterest, shared that, at Pinterest, there is a weekly meeting where SREs share what they spent time on. For another helpful “day in the life” story, take this account of an average OpenShift SRE’s day. Nikita spends her day responding to open JIRA cards, handling incidents, pushing code to GitHub and syncing with SREs in other regions when shifts change.

    Time Well Spent

    So, how does an SRE allocate their time? As Curtis explained, the ideal goal is a 50/50 split between time spent in work mode and time trying to automate that work away. Of course, this is more like a sliding scale, he admits. When things are broken, attention naturally shifts toward more manual work, says Curtis. While there may be less automation upfront, the scale balances out the more you build.

    This is similar at other institutions too. For example, in an interview with DZone, Paul Greig explained that half of his time is spent on service reliability upkeep and half on toil reduction. John Turner, SRE at Squarespace, said some 70% of his time is spent writing code—much of it automation code.

    Who’s Fit to Be an SRE?

    As mentioned above, the SRE job requires a specific attitude toward solving operational problems. Curtis described this person as “someone who hates the monotony of doing something over and over.” This person should have a drive to continuously solve new problems because as soon as you’ve automated one thing, you move on to the next, he said.

    Don’t assume a role with high automation equals an easy paycheck. We’ve all heard the story of the system admin who secretly automated their job away and never told a soul. While this may fly in other roles, the job of an SRE is never finished. “You’re never going to run out of stuff to optimize,” Curtis said.

    Again, the SRE role is a blend of many different activities. You will likely interface with different developer teams, too. Since the role involves this type of interaction, communications skills and understanding are a must.

    Final Thoughts

    The SRE practice is wide and varied—each company may have its unique flavor. Looking to the future, there are plenty of use cases for machine learning to further empower SRE practices, said Curtis. This is especially relevant in security automation, where algorithms could be trained against real attacks to flag suspicious behavior. Or, with the right amount of data, predictive analytics could be applied to anticipate high CPU peaks, informing server utilizations.

    In both scenarios, Curtis stressed the importance of observability. “It really gives you the ability to look at data and to ask a question later you didn’t realize you needed to ask,” he said. This power hinges on easy data transformation to make things speak the same language. That’s why his team opted for Cribl, that allowed them to normalize that data on the fly and replay it later. “The ability to change data and morph it—that’s the power observability gives you.”

  • Best of 2022: SRE Vs. Platform Engineering: What’s the Difference?

    Best of 2022: SRE Vs. Platform Engineering: What’s the Difference?

    As we close out 2022, we at devopsy.kinsta.cloud wanted to highlight the most popular articles of the year. Following is the latest in our series of the Best of 2022.

    Site reliability engineering (SRE) teams and platform engineering teams share similar goals—like maximizing automation and reducing toil—and similar methodologies. But they have different priorities, and use somewhat different tools to achieve them.

    What are SREs? What are platform engineers? How is each role similar and different? This article will answer all your questions.

    Responsibilities of SREs and Platform Engineers

    The main responsibility of site reliability engineers is ensuring that IT systems are reliable, which means that the systems meet performance requirements. Part of their job includes working with developers and IT operations teams to maximize the reliability of applications as they move down the software delivery pipeline.

    Meanwhile, platform engineers focus on managing and optimizing the software delivery process. You could think of this role as one that translates DevOps principles into practice by finding ways to implement continuous delivery, continuous improvement and other DevOps priorities.

    Thus, both SREs and platform engineers play a role in managing the software delivery process and finding ways to make it as smooth and efficient as possible. They also share a common enemy—toil—in the sense that both groups seek to avoid manual, inefficient processes by automating as much as possible. SREs automate complex incident response operations using tools, for example, while platform engineers might deploy methods like GitOps to automate some aspects of software delivery.

    Differences Between SRE and Platform Engineering

    That said, SRE and platform engineering are distinct roles. The key differences boil down to:

    • Goals: The main job of SREs is maximizing reliability, which is different from optimizing the speed and efficiency of software delivery operations. Theoretically, you could have a highly reliable system even if your software delivery chain is manual and slow.
    • Scope of role: Software delivery operations are the main focus of platform engineers. SREs care about software delivery, too, because the way applications are created plays a role in reliability and fixing issues. But SREs also have many other responsibilities, like incident response and helping to manage infrastructure, which fall beyond the scope of software delivery.
    • Tools: SREs rely on tools that help them discover and solve various types of reliability issues. In contrast, platform engineers leverage tools like source code managers and continuous integration (CI) servers to help automate software delivery.

    So, although SREs and platform engineers may use similar methodologies and possess similar skills, their day-to-day operations tend to look quite different.

    Should You Pursue an SRE or Platform Engineer Career?

    Given the skills overlap between SRE and platform engineering, some engineers are a good fit for either role. But which one is better, from a career perspective?

    Salary-wise, there’s not a whole lot of difference. Glassdoor pegs the average salary of platform engineers at about $115,000 compared to $127,000 for SREs. SREs may earn a little more (and it’s worth noting that SRE salaries can vary widely), but the difference in pay is not as great as that between, say, IT operations engineers (who make a mere $77,000, according to Glassdoor) and SREs.

    The roles are also similar in terms of demand. Unlike software engineering or even DevOps engineering, SRE and platform engineering are both roles that have begun to become popular only in recent years. SRE as a concept has been around for a while—it originated at Google in the early 2000s—but it wasn’t until recently that most companies began seeking SREs for their teams. Likewise, platform engineering didn’t become a thing until the advent of microservices and cloud-native everything pushed companies to devote more engineering resources to manage their increasingly complex software delivery processes.

    What this means is that, at least for now, it’s easy to find jobs in SRE and platform engineering as long as you have the right skills. Many companies are eager to hire for both types of roles.

    Choosing the role that is right for you, then, depends mostly on your preferences and how you like to work. The life of a platform engineer is likely to be somewhat more predictable than that of an SRE because platform engineers don’t have to take the lead in managing incidents when something breaks at 2:00 a.m. On the other hand, SREs enjoy a more diverse set of responsibilities, which can make the job more exciting—especially if software delivery tools like Git or Jenkins don’t make you excited to get out of bed in the morning.

    Conclusion

    Platform engineers and SREs play central roles in automating complex processes and eliminating toil. But they tackle these issues from different angles and they use different tools. The right role for you depends on what you enjoy doing most.

  • Blue-Green Deployment: What Are the Options?

    Blue-Green Deployment: What Are the Options?

    Blue-green deployment is a change management strategy for software releases. Blue-green deployments require two identically configured hardware environments. One environment is active and serves end users while the other remains idle.

    Blue-green deployments are typically used for applications with strict uptime requirements. First, new code is released to staging environments and fully tested. Once the code is reviewed, the team adjusts the router configuration to redirect application traffic to the staging environment. This staging environment then becomes the production environment.

    If problems are found after the switch, the team switches traffic back to the old production environment and continues running the original version. Once the new code is validated in production, the team can update the code in the idle production environment, and use it to test the next release. For more background, see this detailed blog about the blue-green deployment pattern.

    Blue-Green Deployment Benefits

    Here are some of the main advantages of blue-green deployments.

    Standby System
    A blue-green deployment always ensures a server is on standby, providing a crucial backup when the system fails. In addition to facilitating software updates, this approach improves risk management, allowing you to switch to the backup server during a malware breach.

    Redirecting traffic to the other system version is easy because it has the same infrastructure. The system can stay live and functional while the teams fix issues.

    Smooth, Fast Releases
    A blue-green deployment allows product owners to push software to production quickly. It offers the flexibility to release an update at any time, with no downtime required. End-users don’t feel the impact of each release. DevOps teams can also benefit from smooth releases because they don’t have to race to meet deadlines for scheduled outages.

    Simple Rollback Process
    Rolling back an update is also fast in a blue-green deployment. Simple rollbacks reduce the risk of experimenting in a production environment. You can implement rollbacks by setting the application to read-only or using a load balancer to handle active transactions during the cutover. This can be significant for Kubernetes security because if security vulnerabilities are discovered in the cluster, you can easily roll back to a previous safe version.

    No Downtime
    A blue-green deployment allows you to avoid downtime, whether scheduled or unexpected. You can shift users to the other model during maintenance checks and fixes. Upgrades can occur anytime because there is no need to wait for times with lower traffic (i.e., midnight).

    Testing in Production
    Testing in production allows you to check a live product’s functionality, showing how it performs in the real world. The drawback of this approach is that it can expose end-users to bugs during testing. A blue-green deployment lets you test the product in an inactive production environment, minimizing the risk of bugs making it to the live environment.

    Blue-Green Deployment in Kubernetes

    Many development teams are migrating to Kubernetes as an environment for development, testing and production deployments. Kubernetes makes it easy to deploy applications and can also be used to automate blue-green deployments.

    However, Kubernetes does not provide out-of-the-box blue-green deployments. It has a Deployment object that allows “rolling updates”—this allows you to update your applications without downtime by incrementally replacing pods with the latest version of an application.

    This is similar to a blue-green deployment but doesn’t offer all the benefits. Rolling deployments can make it difficult to roll back if there are issues with the new version. You might require Kubernetes health checks to determine the status of pods within a deployment. Applications might take time to roll out, while the pure blue-green pattern allows you to switch over to a new version instantly.

    Blue-Green Deployment in Kubernetes: What are the Options?

    Argo Rollouts
    Argo Rollouts is a set of Kubernetes controllers and CRDs that provide advanced deployment features for Kubernetes such as blue-green and canary deployments, experiments, and other progressive delivery capabilities.

    Argo Rollouts optionally integrates with Kubernetes ingress controller implementations and service meshes, leveraging traffic shaping to incrementally switch traffic to new versions during updates. Rollouts can also query and interpret metrics from other systems to validate key KPIs, and automatically promote or roll back releases.

    Flagger
    Flagger is a progressive delivery tool that automates the release process of applications running on Kubernetes. It reduces the risk of introducing a new software version into production by gradually migrating traffic to the new version while measuring metrics and performing conformance testing.

    Flagger implements multiple deployment strategies (canary releases, A/B testing, and blue-green deployments) and integrates with various Kubernetes ingress controllers, service meshes, and monitoring solutions.

    GitLab CI/CD
    GitLab is a collaborative DevOps platform and open-source code repository for large software development projects.

    In addition to a code repository, GitLab also provides CI/CD automation and issue tracking. GitLab repositories allow the hosting of different software versions and entire development pipelines, allowing users to roll back software and environments in case of unexpected problems.

    GitLab supports both manually triggered deployments and scheduled deployments to Kubernetes production systems, using progressive deployment (including blue-green deployment).

    CircleCI
    CircleCI is a CI/CD platform that helps engineering teams build, test, and deploy software, while viewing code changes in real-time in a dashboard UI.

    CircleCI can be deployed to virtually any target and can be easily configured to integrate with other services, for deployment strategies such as feature flags, blue-green and canary deployments. It supports both fully automated deployment processes or a process with manual approvals, with the ability to easily customize deployment configuration.

    Conclusion

    In this article, I explained the blue-green deployment pattern, its benefits, and how it can be beneficial for Kubernetes deployments. I introduced four tools that can help you implement blue-green deployments in your Kubernetes clusters:

    ● Argo Rollouts – Part of the open source Argo project. Includes Kubernetes controllers and CRDs that provide advanced progressive deployment features.
    ● Flagger – An open source progressive deployment tool for K8s that supports canary releases, A/B testing, blue-green, and more.
    ● GitLab CI/CD – Supports both manually triggered deployments and scheduled deployments to Kubernetes production systems.
    ● CircleCI – Supports deployment to Kubernetes clusters, with deployment strategies such as feature flags, blue-green and canary deployments.

    I hope this will be useful as you learn to implement progressive deployment patterns in your Kubernetes environment.

  • Switching From FluentD to Vector Log Aggregation Tool

    Switching From FluentD to Vector Log Aggregation Tool

    Log files are extremely important to the data analysis process as they contain essential information about usage patterns, activities and operations within an operating system, application, server or device. This data is relevant to a number of use cases across an organization from resource management, application troubleshooting, regulation compliance and SIEM and business analytics and marketing insights. To manage logs created by these use cases and make use of this wealth of data, log aggregation tools enable organizations to systematically collect and standardize log files. However, choosing the right tool can be quite challenging.

    This blog will detail and compare the popular open source fluentD and Vector tools for log aggregation.

    fluentD Configuration and Efficiency Calculation

    When using orchestration tools like Kubernetes to deploy containers or other API resources, there is a need for a log aggregator to store the pod or node logs in a cloud platform. For a particular requirement, fluentD was used as a log aggregator tool to push K8s pod logs to cloud storage buckets with a sample configuration as shown below:

    <match kubernetes.**>

    @type <cloud platform name>

    project <project name in cloud platform>

    keyfile <credential json to access the cloud storage> bucket <cloud storage bucket name> object_key_format <name for the file to be used>

    path <file prefix/path where the file have to be stored>

    <buffer tag,time>

    @type file

    path /var/log/fluent/gcs timekey 1m timekey_wait 30 timekey_use_utc true flush_thread_count 16 flush_at_shutdown true flush_mode interval flush_interval 1 chunk_limit_size 10MB retry_max_interval 30 retry_wait 60

    </buffer> <format>

    @type json </format>

    </match>

    Using this system, fluentD was pushing only 47.62% of total logs to cloud storage. Since there was a loss of more than 50%, changes were made to the configuration. In most of the changes, the efficiency was somewhere between 40% and 50%, with a maximum efficiency achieved at an average 67% for an entire day. Below are some of the changes made along with the percentage of logs that were pushed to cloud storage:

    <buffer tag,time> @type file

    path /var/log/fluent/gcs timekey 1m timekey_wait 30 timekey_use_utc true flush_thread_count 16 flush_at_shutdown true retry_max_interval 60 retry_wait 30

    </buffer> Efficiency:- 46.32%

    <buffer tag,time> @type file

    path /var/log/fluent/gcs timekey 1m timekey_wait 30 timekey_use_utc true flush_thread_count 16 flush_at_shutdown true

    </buffer> Efficiency:- 49.89%

    <buffer tag,time>

    @type file

    path /var/log/fluent/gcs timekey 10m timekey_wait 0 timekey_use_utc true flush_at_shutdown true

    </buffer> Efficiency:- 37%

    <buffer tag,time> @type file

    path /var/log/fluent/gcs timekey 30 timekey_wait 0 timekey_use_utc true flush_thread_count 15 flush_at_shutdown true

    </buffer> Efficiency:- 60.88%

    <buffer tag,time> @type file

    path /var/log/fluent/gcs timekey 1 timekey_wait 0 timekey_use_utc true flush_thread_count 16 flush_at_shutdown true flush_mode immediate

    </buffer> Efficiency:- 66.77%

    Vector Deployment, Configuration and Resultant Efficiency

    To improve this further, the open source Vector tool by Datadog was also considered. This tool was suitable for K8s setup with a similar configuration as fluentD and was installed in the nodes.

    A Helm command was used to clone the official repository in its VMs; the configuration was changed as described below and installed it as an agent. Vector comes in two working modes: Agent and aggregator. While agent is the plain mode that pushes logs/events from source to destination, aggregator is used to transform and ship data collected by other agents (in this case, Vector).

    The installation of this tool requires a Helm repository in the local machine to fetch the source code. Hence the below commands were run in a sequential pattern before installing Vector in a K8s cluster:

    helm repo add vector https://helm.vector.dev (Adding vector repo to helm list)

    helm repo update (Updating the helm repos)

    helm fetch –untar vector/vector . (command to clone the repository to local machine)

    Configuration:-

    data_dir: /vector-data-dir

    sources:

    <Custom source id>:

    type: kubernetes_logs (because we are using kubernetes as our source)

    exclude_paths_glob_patterns: <Array of directories which has be excluded when collecting the logs from the nodes> (Optional)

    sinks:

    <Custom sink id>:

    type: <Destination cloud storage>

    inputs: <Array of source id’s from where log has to be pushed>

    bucket: <Bucket name of cloud storage>

    key_prefix: <Path inside the bucket where the logs has to collected> (Optional) encoding:

    codec: <Encoding of the log file> (Optional) Command to install the Vector:-

    helm install vector . –namespace vector

    After deploying Vector in the development environment and testing it, the efficiency was ~100% with negligible loss. The switch was then made to Vector and deployed in the production environment. Vector can ship up 100,000 events or logs/sec, which is a very high throughput rate compared to other tools for log aggregation performance. Vector was able to achieve 99.98-100% efficiency even in the Kubernetes production cluster.

    To learn more about how DataOps can enable highly performant data pipelines with real-time logging and monitoring, watch this video. 

  • SRE Survey Reveals Major Technical and Cultural Challenges

    SRE Survey Reveals Major Technical and Cultural Challenges

    Catchpoint, in partnership with Blameless, today published an annual survey of 559 site reliability engineers (SREs) that found 59% of respondents didn’t view tool sprawl to be a major concern. Another 40% said tool sprawl is a moderate (33%) to serious problem (8%).

    More than half of respondents said they build as much as 30% of the tools they use themselves, with more than half (54%) noting their organization tracks three or more different types of telemetry data to drive observability. The top three types of telemetry data collected are infrastructure (62%), application (58%) and network monitoring (55%) and, on average, the survey suggested the median toil level of SREs dropped 5% year-over-year.

    Just under half of respondents (46%) also noted they saw no or low value from artificial intelligence for IT operations (AIOps) compared to 30% that have seen moderate to high value. Another 25% are still unsure.

    Finally, the survey concluded that organizations that have adopted a “just culture”—where organizations ensure that incident reporting is not met with punitive measures—are 500% more likely to be Elite performers in terms of the DevOps Research and Assessment (DORA) metrics defined by Google.

    Leo Vasilou, director of product marketing for Catchpoint, said that the survey results provided some insights into the challenges SREs face as they strike a balance between trying to achieve DevOps goals and the fact that hiring has become more constrained during an economic downturn.

    That stress, however, has less to do with managing toolchains than it does ensuring that applications driving critical business processes are consistently available, he noted.

    SREs have emerged as a distinct DevOps function in recent years, focused almost exclusively on programmatically managing the dependencies that exist between a wide range of applications and the underlying infrastructure upon which they depend. Optimizing applications in the cloud-native era has become more challenging because the number of dependencies that exist between the microservices that make up a modern distributed computing environment continues to exponentially increase. In many cases, applications are continually added to IT environments without a commensurate increase in the overall size of the SRE team.

    Regardless of the economic climate, hiring and retaining SREs remains a challenge given the demand for IT professionals with those skills. Of course, there is no formal SRE certificate that is widely recognized so who qualifies to be an SRE tends to vary from one organization to the next. The one thing that is generally agreed upon is that SRE automate a wide range of tasks that would otherwise require multiple IT administrators to perform. Glassdoor also reports that, on average, an SRE makes north of about $125,000, which ranks among the highest salary level within any IT organization.

    Each organization, depending on their geographic region, would need to determine how many IT administrators they could replace if they hired an SRE. That doesn’t mean IT administrators that rely on a wide range of graphical tools to manage IT tasks are going away any time soon, but as DevOps continues to evolve, the dynamics between SRE and IT administrators also will continue to evolve.

  • Of Max and Min: The Non-Interference Prime Directive (for Visibility)

    Of Max and Min: The Non-Interference Prime Directive (for Visibility)

    Last issue, I cited CPU utilization as an example of a metric that is often misused to describe/explain/infer system performance and asserted that improved visibility can help to overcome such misuse. In this issue, I will expand on what improved visibility means and present two case studies that illustrate a recent antipattern that I’ve noticed in visibility: Interference caused by visibility interfaces.

    I will describe some properties of ideal visibility interfaces with some real-world analogies. Together with two case studies of performance problems stemming from interfering monitoring interfaces, I will explain why interference can be so damaging to observability efforts. Because so few libraries and applications provide visibility through ideal interfaces, I also continue to argue for better visibility primitives from our operating systems.

    Clarifying Visibility

    Observability is a big deal in the DevOps and SRE communities. We cannot know how well our systems are doing without visibility into their state. Unlike Scotty on Star Trek, we absolutely should not rely on gut feeling to intuit the health of the engines that drive our enterprise systems. We have to build our systems to make their internal state visible to the outside world.

    But what is not often discussed is the degree of visibility and the associated cost. A system’s visibility is not a binary “yes/no” attribute. Just as in the physical world, there are qualities to visibility that impact how observable a system actually is:

    • Is the visibility continuous or is it discrete (in either time or space)?
    • Does the act of observing perturb the system?
    • Can everyone observe or can only a few agents observe and report to everyone else?
      • Can everyone observe at the same time or is it one at a time?

    Let’s ground these attributes of visibility by looking at some examples in the physical world. In the first article of this series, I mentioned that there is a lack of standardized language used in performance engineering. As far as I know, there is no standardized language around the attributes of visibility, so the adjectives that I am using are by no means “standard”–but the distinctions they identify are important.

    Continuous Vs. Discrete Visibility

    When in London, if I can see one of Big Ben’s1 four faces, I can always know what time it is just by looking up. My access to the time of day is continuously available. But if I can’t see any of the faces, I can still rely on the chimes—except that the bells only chime once every 15 minutes. This means that if I can’t see any of Big Ben’s four faces, my access to the time of day will be discrete.

    If I witness an accident, the continuous access to time allows me to precisely note the time of the accident. If I have to fall back to relying on the chimes, the time that I attribute to the accident becomes less precise.

    Likewise, in our cars we often need to know what our current speed is (e.g., as we approach speed traps or enter school zones). It would be absolutely useless if our speedometer reported our speed in five-minute snapshots. I do not want to know how fast I was going three minutes ago. I need to know how fast I am going now!

    All other things being equal, continuous visibility is preferable. Being able to examine a system’s state on demand is far preferable to having to wait for some arbitrary interval to pass before that information becomes available—unless there is an excessive cost to examining the system state in real-time.

    Overhead, Interference and Multiple Viewer Contention

    Measurement overhead is likely the type of cost that most people are familiar with—and the type of measurement cost that many of us focus on. The time to place down a ruler to measure the dimensions of a sheet of paper or the time that it takes to make inter-process communication calls to obtain a service’s state are costs associated with taking a measurement. Of course, we want this measurement overhead to be as low as possible, but we can sometimes live with overhead because the cost is mostly borne by the observer.

    Then there are measurements that interfere with the operation of the system being measured. For example, take the annual physical exams that our doctors recommend. The purpose of these exams is to take measurements of the state of our bodies to detect health regressions. Pretty important stuff. But these exams are intrusive. We have to take time off from work, break our daily routine and trek over to the doctor’s office to get poked and prodded. Some people even skip their annuals because it is so disruptive to their lives. Many of the exciting advances in consumer medical devices essentially facilitate more continuous monitoring of vitals so we can rely less and less on these intrusive annual physicals. Again, continuous visibility is preferred!

    In computer systems, it is virtually impossible to take software-based measurements that don’t contend with the target software for hardware resources. So, implementing visibility in software means that some interference is unavoidable. But, contending for software resources like software locks and critical regions is another matter entirely. As such, we must be cognizant of contention for software resources when designing our systems for visibility. This is the essence of the Non-Interference Prime Directive for Visibility.


     

    A Non-Interference Prime Directive From the PMWG

    The participants in the Performance Management Working Group (PMWG) had different goals and priorities. My priorities lay in establishing a minimally intrusive low-level visibility interface for operating system and process metrics. This became the Data Capture Interface (DCI) layer in the Universal Measurement Architecture specification.

    A key part of the DCI included this statement about the performance impact of monitoring:

    1.2.2 Performance

    The addition of any metrics acquisition subsystem should not noticeably affect the performance of the measured system. (Many performance tool builders assert that system performance should not be altered by more than 5% when there is measurement activity.) Although it is beyond this specification to stipulate a performance degradation figure, that figure belongs in an implementation’s design specification, the performance goal does impose a requirement that the programming interfaces specified in this document be capable of being implemented in the most efficient manner possible on the target operating system.

    I actually wanted something stronger than a generic statement about performance impact in the specification and thought we should provide a reference implementation that would embody the key principles of low overhead, low interference and low contention. To that end, I prototyped a version of UNIX SVR4 where the kernel sysinfo data structure used by the sar/sadc utilities was placed on a page-aligned area of kernel address space. I also made sure that the rest of the page was not occupied by any other data (to address security concerns) and arranged for that page in kernel address space, which is normally protected against reads and writes from user space, to be readable (but still not writable) by all user processes at a fixed address in the user address space (it was a prototype to demonstrate how “things could be”).

    Sadc (the data collection component of sar) normally accessed the sysinfo data structure via /dev/kmem (a special file that gives file access semantics to the kernel virtual address space). On my prototype system, I modified sadc to simply dereference the fixed virtual memory that I placed sysinfo into. No open, lseek and read—just memory dereference. On the 3B2/400 system on which my prototype ran, running sadc once a second normally took almost 5% of a single CPU. On my prototype system, I was able to run sadc 100 times a second with almost no measurable CPU usage. Additionally, in my prototype, EVERY process had read-only access to the sysinfo data via simple memory dereference. The system became super visible—with virtually no overhead. Everyone could look at sysinfo at any time at the cost of memory access. Visibility Nirvana!

    Alas, Nirvana nixed; paradise lost. PMWG participants did not wish to put the requirements of a reference implementation on their kernel developers. Instead, we opted for the weaker statement about performance you see above.


    Just as with annual physical exams, a computer system measurement implementation that results in the slowing down of the system presents a tremendous disincentive to taking that measurement.2 Measurement interference is something that we need to design out of our implementations—not design into them.

    For example, if a system maintains a linked list of objects that are actively being added and removed, and traversal and manipulation of this linked list is protected by read and write locks, an implementation of a monitoring interface that needs to traverse this collection of objects in read-only fashion should not participate in this locking protocol. This statement might rankle some software engineers who are used to “data integrity at all costs,” but this highlights some of the differences in priorities between general software engineering and the practical needs of performance engineering.3 Implementing monitoring interfaces that cause software interference is counterproductive—they won’t be usable when they are most needed.

    So far, we have only considered a single observer of our systems. When there are multiple observers, we also have to ask whether the observers interfere with each other. There are plenty of examples in real life where this happens. For example, if ten people are trying to measure the dimensions of a piece of paper, physical constraints probably allow only for two or four measurements (at most) to be taken at a time (i.e., assuming an organized pipeline of participants measuring width and then height). An even more realistic example of serialized observer access might be the portholes in the lower decks of a cruise ship. Some of the smaller portholes only allow one person to view the outside at a time. So, when a pod of whales swims by, viewers have to queue and take turns to gain access to observe them.

    With computer systems, measurement contention between multiple observers also tends to discourage observation—not because everyone is so polite but because no one wants to get stuck in a line.

    Fragmented Vs. Holistic Visibility

    A final dimension of visibility is related to the field of vision. In the physical world, this is illustrated by comparing the porthole view from inside a cruise ship with the wide open, unobstructed view from the top deck.4 Compared to the top deck, portholes only provide a partial view of the ocean. One sometimes needs to stitch together the views from multiple portholes to get a more complete view of the outside world. The importance of the more complete view is the inherent bigger picture—where each fragment provides context for and about neighboring fragments.

    In computer systems, visibility is inherently fragmented. Each component provides a visibility portal (or not) into its own state. Like the portholes on the lower decks of cruise ships, we can approximate a holistic view if we are able to query the state of each component in a reasonably timely fashion. Again, this is only possible if each component supports continuous visibility. Unfortunately:

    • Many key low-level components do not provide any visibility.
    • Many other components only provide discrete visibility.
    • Some limit visibility even further by providing discrete visibility through network sockets with endpoints that are off-host. As a result, co-located components are unable to examine each other’s visibility interfaces in any practical manner.

    In turn, the opaque, fragmented views that result from the discrete visibility in many components results in a fragmented mentality among developers. Engineers develop a mindset that they are implementing visibility only for themselves and their components, rather than thinking about their visibility as part of a whole—which provides a circular argument for justifying the discrete view they fall back on.

    Rather than thinking of passengers on a cruise ship and portholes, think of the components co-executing on a host as workers in a factory—with data moving through and between them. The current fragmented view places each worker in their own room, where they are unable to see the state of the other workers. With a holistic view supported by continuous visibility into one’s neighbors, workers can make better plans and decisions. And “factory monitors” can get a more holistic view of events and better correlate different components’ states. Being able to build useful context around observations is a key attribute of observability.

    In contrast, modern UNIX and Linux systems support continuous visibility for operating system and process metrics through the /proc interface. We can query /proc for a supported metric at any time. The utility (and success) of the /proc interface is unquestioned–being able to access process and system metrics through the filesystem namespace is a fantastic idea.5

    Applications and libraries have grown accustomed to the ability to query standard system metrics at will. If this mode of continuous visibility were to spread to the full stack, it stands to reason that the ecosystem would evolve to benefit from this enhanced observability. This should provide an impetus for the operating system to provide primitives to facilitate continuous visibility for the entire stack.

    But while we wait for visibility nirvana, there are some practical problems that need to be addressed. Some important visibility interfaces that currently exist are violating the prime directive in a big way.

    Prime Directive Violations

    I delivered a talk at SRECon 2021 entitled Latency Distributions and Micro-benchmarking to Identify and Characterize Kernel Hotspots, in which two of the hotspot case studies are examples of standard, commonly-used visibility interfaces that violate the Non-Interference Prime Directive. Let’s examine those two cases.

    When the Cost of Running Netstat is Too Dang High

    We recently discovered that netstat can seriously delay the creation and destruction of UNIX domain subsystem (UDS) sockets on Solaris. More specifically, in Solaris, the kstat mechanism to query for the list of all active UDS sockets (an ioctl call) can take seconds of CPU time, especially when there are tens of thousands of the sockets in the system. By itself, this makes logical sense and is not a problem since more sockets means more data transferred from the kernel to the user space. But the impact of a long netstat run time on actual UDS socket creation and destruction is surprising (and disappointing).

    Here is the output of a program I wrote which collects a logarithmic histogram of the socket() and close() times for creating and destroying UDS sockets 100K times on a Solaris 11.3 system:

    <1us

    <10us

    <100us

    <1ms

    <10ms

    <100ms

    <1sec

    >1sec

    max

    socket

    0

    0

    72556

    27433

    11

    0

    0

    0

    1967055ns

    close

    0

    98262

    907

    815

    16

    0

    0

    0

    1364475ns

    Now, here are the results from the same program, but this time I’ve concurrently run a single instance of netstat -f unix:

    <1us

    <10us

    <100us

    <1ms

    <10ms

    <100ms

    <1sec

    >1sec

    max

    socket

    0

    0

    39006

    60976

    18

    0

    0

    0

    2137995ns

    close

    0

    96837

    1388

    1757

    15

    2

    1

    0

    308073600ns

    Look at how the single netstat call has pushed the maximum close time from about 1ms to over three seconds!6 And it looks like the distribution of socket() times that was clustered in the 10-100usec range has increased to be more clustered in the .1-1msec range. The act of running netstat has a huge impact on the time to create and close UDS sockets.

    Disabling netstat is not the right long-term solution, as doing so would eliminate key visibility. Artificial throttling of netstat usage is also not the right long-term solution, as this compromises the timeliness of visibility (i.e., continuous visibility). The right thing to do is to eliminate this tight coupling between netstat monitoring and the UDS.

    When PS Stands for “Pretty Slow”

    Before Linux aficionados smugly dismiss monitoring interference as only a Solaris problem, there is potentially an even bigger problem on Linux. There, the monitoring contention is seen by accessing /proc itself and is of the “contending observers” type.

    Let’s look at running concurrent instances of “ps auxww” on one of our Linux development boxes with 36 cores and 72 hardware threads (RHEL 7.6):

    Concurrency

    Wall time (avg)

    User time

    Sys time

    1

    .984

    .081

    .902

    2

    1.269

    .071

    1.013

    4

    3.043

    .066

    1.429

    8

    4.106

    .070

    1.396

    As we can see, with increasing concurrency, the average wall time for ps completion goes up (along with system CPU time). The ps instances compete with one another!7 This is even more surprising since ps is essentially a read-only operation.

    Further tests showed that /proc traversal for processes and threads not only contend with each other, but also that they contend with access to other, non-process related special files under /proc (e.g., /proc/vmstat). This is significant because so many libraries and applications depend on non-process data available through /proc to make runtime decisions.

    My colleague Gary Liku will be presenting additional findings around this /proc contention problem at SRECon22 EMEA in late October.

    What Happened?

    In the old days, tools like ps and netstat would obtain their data by opening the special file /dev/kmem – a file-based interface to the kernel virtual address space. If we knew the virtual address for an object and its size, we could simply seek to the virtual address in that file and read() the object. The decoupled nature of this read meant that it was impossible to do any synchronization or coordination with actual code that operated on the object. An object could change in the middle of a read.8 As mentioned earlier, the expectations around monitoring data consistency can be looser than the standard data flows that most software engineers deal with. This decoupled data access adhered to the Non-Interference Prime Directive and suited the monitoring use case very well.

    In modern UNIX systems, the use of /dev/kmem has fallen out of favor–and for good reason. In addition to the performance overhead of seek/read to access kernel objects, /dev/kmem gave all-or-nothing access to the full kernel virtual address space. This meant that applications that did monitoring via /dev/kmem had to also be trusted with elevated privileges.

    The general purpose decoupled access through /dev/kmem has been replaced with (potentially) coupled access to kernel objects through interfaces like /proc on many UNIX and Linux systems. But, as we have concluded, just because coupled access is allowed does not mean that it should be exercised without consideration of the interference cost.

    Assuming that a visibility interface will be used sparingly or sporadically often turns out to be a bad assumption. The more useful a visibility interface, the more often it will be used.

    Visibility in User Space

    As mentioned earlier, while the operating system provides continuous visibility interfaces (e.g., /proc) for accessing well-known system and process metrics, application code generally does not. It can be argued that, in avoiding continuous visibility interfaces, applications are also able to avoid the problem of interference and observer contention–and that would be a valid argument. But, I feel that the ideal of holistic views of the co-located components of a system is so compelling that applications should either (1) lobby for the operating system to provide proper continuous visibility primitives for applications (/proc provides an excellent framework for building such primitives) or (2) implement their own continuous visibility interfaces.9

    Java and the JVM provide examples of how continuous visibility interfaces can work in user space. Very early on, Java’s designers saw the benefit of continuous visibility into JVMs and came up with the Java Management Extensions (JMX) framework. Through this framework, the JVM, Java libraries, and Java applications are able to expose metrics through getters on management beans. These getters can be discovered through a common namespace. JMX also allows external clients to invoke these getters through a standardized remote procedure call mechanism.

    Getters can be implemented as simply as returning the current value of an object that summarizes code state, or implemented with arbitrarily complex code–including invoking getters on other management beans or querying remote databases. But, the overhead and non-interference concerns outlined earlier should apply to getters implemented for performance visibility.

    Finally, it is interesting to note that Oracle (and perhaps other) JVMs also implement a lower-level metric exposure mechanism that leverages a memory-mapped file to provide a shared memory interface to JVM metadata and some low-level metrics.10 Even with the continuous visibility provided by JMX, JVMs also recognize the advantages of lower overhead, more decoupled, coordination-free visibility utilizing shared memory.

    We should all keep the prime directive in mind and design our visibility mechanisms in the least intrusive, most decoupled manner that is practical.  Or as users, require that the visibility mechanisms that we use adhere to the prime directive.


     1Yes, I know; Big Ben is not actually the name of the tower with the clock faces: https://en.wikipedia.org/wiki/Big_Ben

     2These implementations are not useless. But they are generally relegated to being used for performance debugging – often in non-production environments.

    3Similar compromises are taken when building loosely coupled distributed systems—especially in extremely large systems where eventual consistency is an acceptable norm. We need to think of the design of monitoring systems as loosely coupled with the system being observed.

    4Although recent insights from cognitive neuroscience suggests that this complete visual view is actually an illusion created by our brains: https://www.science.org/doi/10.1126/sciadv.abk2480. But the concept of an accurate holistic view of the state of systems remains an ideal goal.

    5Unfortunately, no one has chosen (yet) to implement a low cost, low interference, low contention mechanism like the one I prototyped for UNIX SVR4.

    6The amount of impact of netstat on UDS socket creation and close turns out to be a function of the number of UDS sockets on the system. The more UDS sockets, the greater the impact.

    7This behavior gets more pronounced as the number of lightweight processes/threads in the system increases because the overhead appears to grow quadratically.

    8My memory access prototype, which was orders of magnitude less expensive than a read of /dev/kmem, was also decoupled in a similar manner.

    9Everywhere I go, I re-implement my libmetrix C library—metric registration and exposure through memory mapped files which approximates what I believe would be ideal metrics primitives based on /proc. An ideal metrics registration and exposure interface for user-level libraries and applications should be implemented under /proc itself.

    10Similar in spirit to my aforementioned libmetrix library.

    Thanks

    Thanks again to everyone who provided feedback on earlier drafts of this installment. And again, special thanks to Peter Wainwright for helping to get my thoughts better organized for this installment.

  • Of Max and Min: When Performance Engineering Plans Go Awry

    Of Max and Min: When Performance Engineering Plans Go Awry

    Modern software developers have access to powerful tools and services which allow them to quickly develop, demo and deploy fully functional applications. But what happens when the single-user prototype satisfies all required functionality but the user says the system seems slow? Or if the initial implementation turns out fine for one user, but multiple users start to experience delays? Or if users are happy, but the cost of auto-scaling grows prohibitive?

    The Problem with Performance Engineering

    Concern over non-functional aspects of computing systems—response times, resource utilization and costs—falls under the domain of computer systems performance engineering (CSPE). Unfortunately, the practice of CSPE has evolved into something more akin to art than engineering—with few standardized principles and practices. Because software is constantly evolving its languages and abstractions, CSPE practitioners appear obligated to evolve and change their abstractions and languages, too.1 As a result, part of our jobs as performance engineers is to understand what the heck other performance engineers really intend or mean.

    There are many reasons for this state of affairs, but ultimately this lack of a common language and engineering standards for CSPE is a deficiency in the education and training of software engineers. There is very little in the typical university software engineering curriculum that prepares software engineers for doing CSPE. This sometimes leads to practices that are not backed by scientific or engineering principles. As a result, practitioners are forced to “wing it”—creating their own art or hitching their wagons to someone else’s star and learning (or not) through trial and error.


    The PMWG – A POSIX for Performance?

    The Performance Management Working Group (PMWG) was started in the late 1980s during the “UNIX wars,” when computer vendors were feuding over claims to the UNIX leadership mantle and had formed two factions: UNIX International and the Open Software Foundation. The group was unique in that its members included computer systems vendors on both sides of the “war.” Its members put aside those differences to try to come up with performance management standards and practices that would put UNIX on par (at least) with the performance management tools found on mainframes.

    In retrospect, the PMWG was probably the best chance UNIX had for establishing, promoting and enshrining some basic performance engineering principles—a kind of POSIX for performance. Unfortunately, the group failed—in large part, in my opinion, because it put too much priority on the latter stages of the performance management data pipeline and did not spend enough effort toward establishing key primitives. Today, in the absence of established rules and practices for performance engineering, history is repeating itself. Current efforts in observability continue to focus mainly on data presentation and data transport and storage, without much focus on the right metrics and data quality based on basic performance engineering principles. Presentation, transport and storage are important, but the efforts around metrics, logging and tracing coverage and data quality are sporadic at best.


    Inertia, Expediency and Superstition

    Why are more formal, engineering-based practices around CSPE needed? Consider the use of CPU utilization as a key performance indicator (KPI) of system performance. I’m a member of Bloomberg’s Trading Solutions SRE team, which manages hundreds of machines on which the company’s Trading Solutions software runs. We often see or hear statements like “This host’s CPU is too busy,” or “That host is out of CPU resources.” I’ve found that these observations are not actually very helpful and sometimes divert our attention from the real problem(s). When misused as a system KPI, focusing solely on CPU utilization can lead us down the wrong path and draw incorrect conclusions. To understand why, let’s first look at how we assess the performance of real-world, non-computing systems.

    Take fast-food restaurants. One of the most important attributes of fast-food restaurants (besides their health inspection rating) is that they are fast. But we’ve all been to fast food restaurants that are anything but fast. Without actually standing in line and waiting, we can often tell that we will have a slow experience at a fast food joint if there is a long line. The line length gives us a lot of information. Our assessment of the situation is different whether there are 100 customers versus 10 customers versus a single customer waiting in line.

    In the real world, this line length (or queue length) assessment is almost universal. Supermarket checkouts, ATMs, airport security screening, toll booths, elevators and COVID-19 testing are all areas where we apply this semi-conscious assessment. In contrast, we almost never use “cashier utilization” or “self-serve soda fountain utilization” as a way of assessing how slow a fast-food restaurant is. We always say “the lines are long” or, if we actually choose to wait in line, we’ll make the more direct statement that “service is slow.”

    Which brings us back to our computing systems. Why do we reflexively look to CPU utilization when computing systems are slow while, in the physical world, we rely on queue lengths? The question is even more relevant when we consider that the concept of CPU is less well-defined today. Are we measuring the CPU, its cores or hardware threads?2 I believe the contributing factors to this misuse include inertia, expediency and superstition.

    In the early days of computing, CPUs were perhaps the most expensive component of the large monolithic computer systems of the time. Measuring how much these expensive components were being used was an important part of maximizing the financial investment in these large machines. Fortunately, measures of CPU utilization were relatively easy to estimate. Ease of implementation meant that CPU utilization measures were almost universally available.

    The universal availability of this simple metric, combined with some correlation (sometimes weak) between high CPU utilization and system slowness made it a default indicator of systems performance. When a belief becomes ingrained to the point of superstition, even weak correlations are enough to validate and perpetuate it. Better metrics—for example, run queue lengths at the CPU(s)3—can help us shed our superstitions to better understand our systems and lead us in the right direction in identifying and correcting problems.

    Dispelling Superstition and Other Irrational Practices

    Which brings us to the title and purpose of this series. As a title, “Of Max and Min” is meant to evoke John Steinbeck’s classic novella “Of Mice and Men,” which in turn got its title from the famous line in Robert Burns’ poem “To a Mouse”: The best-laid plans of mice and men oft go awry. The two main characters in “Of Mice and Men” fail in their efforts to better their lives during the Great Depression because they are tragically ill-equipped to do so. Similarly, we should not be surprised if plans go awry when software engineers are tasked with doing performance engineering without the proper training in performance engineering principles.

    “Max and Min” also highlights the importance of data analysis and statistics in understanding systems behavior. Effective CSPE requires us to be familiar with concepts in statistics, numerical analysis, and even operations research—in addition to the more standard computer science areas of algorithmic complexity and computer architecture.

    With “Of Max and Min,” in addition to calling out superstitions, I will be pointing out some common mistakes we make and blind spots that we have.4 Through case studies, I’ll illustrate how our blind spots can lead to mistakes that can persist for years. I will also try to cover some basic CSPE principles that I believe are skipped in most software engineering training. Like everyone else, I’ve been winging it for 40+ years. And I’m still learning. If you disagree with any of my points or have further insights into the topics that I am presenting, please let me know.


    1But, as in the application of the principles behind algorithmic complexity, there are some performance engineering principles that can and should be adhered to regardless of the system and language du jour.

    2There are in fact some bizarre implementations of “CPU utilization”. Here’s an example of how AIX “broke” the meaning of CPU utilization on their multiprocessor systems running in hyper-threading mode.

    3UNIX and Linux do in fact have metrics that could be used as CPU queue length indicators.  In a future installment, I will go into the quirks of some of the CPU queue length implementations and further argue for more consistent mathematical bases for queue length metric implementations.

    4For example, have you ever wondered why, after so many outages caused by logging, malloc, DNS and other low-level services, we still don’t have good, out-of-the-box visibility into these and other low-level components? We are accepting key blind spots as a fact of life when we really shouldn’t.

    About Me

    Like many software engineers, I started off studying a different field (Physics). Unlike most software engineers, I’ve always wanted to be a performance engineer. When I started taking computer classes as an undergraduate in Columbia College’s Physics program, I did not wish for a career writing programs in Fortran (yes, it was that long ago). But I did envision myself making systems run better and faster.

    To that end, when I added a Computer Science major to my undergraduate studies, I also added a minor in Industrial Engineering and Operations Research. For those unfamiliar with IEOR, it is a multidisciplinary engineering field that leverages mathematical and analytical methods to address complex system problems like resource allocation, supply chains, wait times, fairness, etc. Tools and methodologies from IEOR are invaluable to CSPE.

    At the start of my career, I joined the Bell Labs Computer Center as a computer systems performance engineer, where I made the somewhat contrarian decision (for 1980) to work in the group supporting their in-house, low-key UNIX systems (as opposed to their commercially popular MVS mainframes). I didn’t realize it at the time, but having access to the source code of the system you support/study can be a boon to understanding. At Bell Labs, I had the opportunity to contribute to the UNIX System V kernel, where I co-developed the first general-purpose kernel and user-land tracing system for UNIX and made significant performance enhancements to the virtual memory subsystem, and participated in the PMWG.

    Since then, I’ve spent the bulk of my professional career working on financial software systems—ranging from market data to messaging to transaction management. I’ve worked on monitoring systems on an enterprise level. I’ve made and witnessed many CSPE mistakes. In my current role as an SRE on the Trading Solutions team at Bloomberg, I’m seeing and helping remedy lots of operating system issues that stem from our runtime scale.


    Thanks

    Thanks to everyone who reviewed this document and provided constructive feedback. Special thanks to Nate McNamara and Peter Wainwright for suggesting substantive organizational and structural improvements. Peter also reined in my default stream of consciousness, run-on style. None of them had any hand in the writing of this paragraph.