<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.3.3">Jekyll</generator><link href="https://thuzxj.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://thuzxj.github.io/" rel="alternate" type="text/html" hreflang="en"/><updated>2024-12-25T17:01:51+00:00</updated><id>https://thuzxj.github.io/feed.xml</id><title type="html">Xingjian Zhang’s page</title><subtitle>Xingjian&apos;s Personal website. Based on [*folio](https://github.com/bogoli/-folio) design. </subtitle><entry><title type="html">The difference between microservices and serverless computing: the event-driven architecture</title><link href="https://thuzxj.github.io/blog/2024/microservices-serverlss/" rel="alternate" type="text/html" title="The difference between microservices and serverless computing: the event-driven architecture"/><published>2024-12-20T00:00:00+00:00</published><updated>2024-12-20T00:00:00+00:00</updated><id>https://thuzxj.github.io/blog/2024/microservices-serverlss</id><content type="html" xml:base="https://thuzxj.github.io/blog/2024/microservices-serverlss/"><![CDATA[<p>TL;DR: The event-driven architecture in serverless computing mitigates the overhead introduced by decomposing the monolithic application into microservices.</p> <p>Microservice architecture and serverless computing are two popular architectural styles for building cloud-native applications. Both of them support automatic scaling, manage instances in containers and decompose complex applications, making them able to be used to build scalable and resilient applications. However, while microservices let the developers manage the interaction between services, serverless computing takes over the infrastructure management totally and provides an event-driven architecture.</p> <p>Microservices decompose the monolithic application into a set of loosely coupled services, while also introducing the network overhead of the communication between services. Different from function calls, the communication between services is usually done through the network. When one service calls another service, it needs to serialize the data, send it over the network, wait for the response, deserialize the data in the response, and continue the execution. What’s more, while waiting for the response, the process of callee service blocks execution and still maintains the state of execution in memory. The waiting limits the ability of the service to handle more concurrent requests.</p> <p>In two cases, this waiting is unnecessary. The first one is that the callee service B returns the response data from service C to service A that calls service B, without any more processing, for example, the confirmation of DB writing. This means that sending the data to service B and deserializing and serializing the data by service B are unnecessary. The second one is that the callee service B only did some simple processes on the response data without using too much or any sensitive context, such as filtering some entries. This waiting is also not necessary if some more APIs are added to service C.</p> <p>The event-driven architecture in serverless computing avoids the unnecessary overhead of waiting for responses and network communication. Cloud vendors provide various components as event sources and event consumers, provide event distribution and management services, and provide asynchronous and decoupled processing mechanisms. Serverless computing provides immediate results through API Gateway or asynchronous results through various event sources.</p> <p>Take AWS as an example, event sources include S3, DynamoDB, API Gateway, EventBridge, Simple Queue Service (SQS), Simple Notification Service (SNS), etc. Event consumers include Lambda, Step Functions, ECS, etc. Event distribution and management services include EventBridge, SQS, SNS, etc. Asynchronous and decoupled processing mechanisms include Step Functions, SQS, SNS, EventBridge, etc.</p> <p>However, the implementation of event-driven computing relies on the modification of application code and the developers’ understanding of the complex workflows. Some other disadvantages, including dependence on specific cloud platforms and the difficulty of migrating stateful applications, also prevent the adoption of serverless.</p> <p>By the way, developers can benefit from event-driven architecture in microservice. <a href="https://github.com/eclipse-vertx/vert.x">Vert.x</a>, a tool-kit for building reactive applications provided by Eclipse, also uses event-driven API to save resources and reach higher throughput.</p>]]></content><author><name></name></author><category term="academic"/><category term="microservice"/><category term="serverless"/><category term="cloud"/><summary type="html"><![CDATA[The event-driven architecture in serverless computing mitigates the overhead introduced by decomposing the monolithic application into microservices.]]></summary></entry><entry><title type="html">Resource Management of Cloud</title><link href="https://thuzxj.github.io/blog/2024/cloud-resource-management/" rel="alternate" type="text/html" title="Resource Management of Cloud"/><published>2024-12-10T00:00:00+00:00</published><updated>2024-12-10T00:00:00+00:00</updated><id>https://thuzxj.github.io/blog/2024/cloud-resource-management</id><content type="html" xml:base="https://thuzxj.github.io/blog/2024/cloud-resource-management/"><![CDATA[<p>Cloud computing keeps growing and provides many kinds of products for various workloads. Cloud providers and academic researchers focus on how to provide the given services with less cost, that is more efficiently. Numerous works focus on improving significant components like resource allocation, instance placement, resource harvesting and so on. Specifically, the development of AI promotes the exploration of AI for systems.</p> <p>As interested in this important problem, I have surveyed it and tried to figure out some research opportunities. Unfortunately, many of them are done and must be done by companies or the cooperation of companies and academic institutes, because of the limitation of characterizing requests’ features, finding practical problems, and validating new ideas in laboratories. However, these works give valuable insights such as how to improve large-scale systems and handle indeterministic workload.</p> <p>This article is aimed to summarize some research works and record some of my thoughts about this problem. If there are any errors in this article, feel free to contact me to correct them and I will appreciate it.</p> <h2 id="brief-introduction-to-cloud">Brief Introduction to Cloud</h2> <p>To abstract and define the problem of resource management, I would like to have a brief introduction of Cloud Computing first.</p> <h3 id="products-in-the-cloud">Products in the Cloud</h3> <p>There are three main cloud computing models, that is Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS). Public cloud providers provide multiple kinds of products in IaaS and PaaS, including:</p> <table> <thead> <tr> <th>Product Type</th> <th>Product Example</th> <th>Computing Model</th> </tr> </thead> <tbody> <tr> <td>Bare-metal machines</td> <td>AWS EC2 Bare Metal</td> <td>IaaS</td> </tr> <tr> <td>Virtual machines</td> <td>AWS EC2</td> <td>IaaS</td> </tr> <tr> <td>Kubernetes Engine</td> <td>AWS EKS</td> <td>PaaS</td> </tr> <tr> <td>Serverless / Function as a Service</td> <td>AWS Lambda</td> <td>PaaS</td> </tr> </tbody> </table> <h3 id="the-deployment-of-the-products">The Deployment of the Products</h3> <p>Given a data center with many resources, how do these different kinds of products run together in the same data center? For the convenience of management and development, the products (may) run hierarchically. Virtual machines are running on the top of physical machines. Containers and container schedulers are running on the top of virtual machines.</p> <p>The process of deployment is composed of several steps, including resource allocation, instance placement and preemption &amp; migration.</p> <h4 id="resource-allocation-specification">Resource Allocation Specification</h4> <p>Users should specify the resource allocation strategy of the cloud products, such as the size of VMs or containers, and the autoscaling configurations of services.</p> <h4 id="instance-placement">Instance Placement</h4> <p>As the resource pool is composed of multiple nodes, the cloud provider should decide the placement of each instance. The placement should consider both the resource efficiency and the additional requirements from users such as affinity configurations. The placement problem can be modeled as Bin-packing problem, where the nodes are bins and the instances are items.</p> <h4 id="instance-preemption--eviction-migration">Instance Preemption / Eviction/ Migration</h4> <p>On nodes with an oversubscription mechanism, part of the instances are able to be preempted, or evicted or migrated to release resources for the more important instances. Preemption and migration reduce the reliability of the affected instances. In IaaS, the preemptible instances are called spot VMs or harvest VMs and are cheaper than regular VMs.</p> <h3 id="cloud-targets">Cloud Targets</h3> <h4 id="from-user">From User</h4> <p>Users have different targets for cloud projects for various kinds of workloads.</p> <ul> <li>For computing workload (e.g. batch processing): Less cost</li> <li>For latency-sensitive workload (e.g. VMs running user-facing service): No resource contention; guarantee for providing all the required resource</li> <li>For dynamic workload (e.g. serverless/microservice services): Dynamic resource allocation that can scale quickly for burst workload; guarantee for meeting SLO (P95 max response latency is smaller than threshold)</li> </ul> <h4 id="from-provider">From Provider</h4> <ul> <li>Meet users’ targets</li> <li>Less cost <ul> <li>Fewer needed physical machines</li> <li>Less power</li> <li>Less carbon footprint</li> <li>Lower scheduling system overhead</li> </ul> </li> <li>More profits <ul> <li>More product selling</li> <li>Higher resource utilization</li> </ul> </li> </ul> <h2 id="improvement-opportunities">Improvement Opportunities</h2> <p>Referring to the three steps of the deployment of the projects, here are several methods to improve resource management.</p> <h3 id="resource-allocation-optimization">Resource Allocation Optimization</h3> <p><strong>Insight:</strong> Specifying the resource allocation strategies may be difficult for developers and operators, replacing the process with automatic frameworks can lead to better results.</p> <details> <summary>Papers</summary> <ul> <li>SelfTune: Tuning Cluster Managers (MS, NSDI'23)</li> <li>With Great Freedom Comes Great Opportunity: Rethinking Resource Allocation for Serverless Functions (IST(ULisboa)/INESC-ID and UCLouvain, MS, EuroSys'23)</li> <li>Karma: Resource Allocation for Dynamic Demands (Cornell, OSDI'23)</li> <li>Golgi: Performance-Aware, Resource-Efficient Function Scheduling for Serverless Computing (HKUST, WeBank, SoCC'23)</li> <li>Autopilot: Workload autoscaling at google. (Google, EuroSys'20)</li> <li>Largescale cluster management at Google with Borg. (Google, EuroSys'15)</li> <li>Quasar: Resource-efficient and QoS-aware cluster management (ASPLOS'14)</li> </ul> </details> <h3 id="oversubscription-of-instances-to-increase-resource-utilization">Oversubscription of Instances to Increase Resource Utilization</h3> <p><strong>Insight:</strong> As the utilizations of instances on the nodes are always below the highest level, the oversubscription (aka overcommitment) strategy is used to put more instances on the nodes to increase the utilization of the nodes. The simple oversubscription method is to set a fixed oversubscription ratio (&gt; 1), and the scheduler can allocate resources to instances whose sum can exceed the total number of the resources of the node. However, oversubscription introduces the possibility of resource contention when utilizations of multiple instances go high. Some works focus on avoiding the problem through characterizing, profiling, predicting, etc.</p> <h5 id="papers">Papers</h5> <ul> <li>Harmonizing Efficiency and Practicability: Optimizing Resource Utilization in Serverless Computing with Jiagu (SJTU, HW, ATC’24)</li> <li>Dynamic Idle Resource Leasing To Safely Oversubscribe Capacity At Meta (Meta, SoCC’24)</li> <li>Prediction-Based Power Oversubscription in Cloud Platforms (MS, ATC’21)</li> <li>History-based harvesting of spare cycles and storage in large-scale datacenters (OSDI’16)</li> </ul> <h3 id="improvement-of-underlying-schedulers">Improvement of Underlying Schedulers</h3> <p><strong>Insight:</strong> The colocation of multiple instances in one nodes depends on the task scheduler of the node. In underlying schedulers, discovering fine-grained improvements can increase resource utilization.</p> <h4 id="papers-1">Papers</h4> <ul> <li>Maximizing VMs’ IO Performance on Overcommitted CPUs with Fairness (The University of Edinburgh, HW, SoCC’23)</li> <li>Improving resource utilization by timely fine-grained scheduling. (CUHK, SOSP’20)</li> </ul> <h3 id="unified-large-scale-resource-management">Unified Large-Scale Resource management</h3> <p><strong>Insight:</strong> The unified resource management system that manages all the machines in all datacenters and schedules all workloads of different priorities can lead to a more flexible and optimized resource utilization.</p> <h4 id="papers-2">Papers</h4> <ul> <li>Optimizing Resource Allocation in Hyperscale Datacenters: Scalability, Usability, and Experiences (Meta, OSDI’24)</li> <li>Gödel: Unified Large-Scale Resource Management and Scheduling at ByteDance (BD, SoCC’23)</li> <li>Workload Consolidation in Alibaba Clusters: The Good, the Bad, and the Ugly (HKUST, Alibaba, SoCC’22)</li> <li>Twine: A Unified Cluster Management System for Shared Infrastructure (Facebook, OSDI’20)</li> <li>Protean: VM Allocation Service at Scale (MS, OSDI’20)</li> </ul> <h3 id="hardware-resource-disaggregation">Hardware Resource Disaggregation</h3> <p><strong>Insight:</strong> Resource disaggregation makes instance placement easier and increases the resource utilization. Currently, storage is managed separately, but CPU, memory and GPU resources are coupled in same nodes.</p> <ul> <li>With Great Freedom Comes Great Opportunity: Rethinking Resource Allocation for Serverless Functions (IST(ULisboa)/INESC-ID and UCLouvain, MS, EuroSys’23)</li> <li>LegoOS: A Disseminated, Distributed OS for Hardware Resource Disaggregation (Purdue, OSDI’18)</li> </ul> <h3 id="resources-harvesting-from-unallocated-resources">Resources Harvesting from Unallocated Resources</h3> <p><strong>Insight:</strong> Preemptible VMs like spot VMs and harvest VMs are much cheaper but less reliable. Some works are aimed at reducing the damage to the applications caused by the stop of preemptible VMs.</p> <h4 id="papers-3">Papers</h4> <ul> <li>Unlocking unallocated cloud capacity for long, uninterruptible workloads (CMU, MS, NSDI’23)</li> <li>Snape: Reliable and Low-Cost Computing with Mixture of Spot and On-Demand VMs (MS, ASPLOS’23)</li> <li>Providing SLOs for Resource-Harvesting VMs in Cloud Platforms (MS, OSDI’20)</li> <li>History-Based Harvesting of Spare Cycles and Storage in Large-Scale Datacenters (UMich, MS, OSDI’16)</li> </ul> <h4 id="applications-of-harvested-resources">Applications of Harvested Resources</h4> <ul> <li>Parcae: Proactive, Liveput-Optimized DNN Training on Preemptible Instances (CUHK, NSDI’24)</li> <li>SpotServe: Serving Generative Large Language Models on Preemptible Instances (CMU, ASPLOS ’24)</li> <li>Faster and Cheaper Serverless Computing on Harvested Resources (Cornell, MS, SOSP’21)</li> </ul> <h2 id="dataset-resources">Dataset Resources</h2> <h3 id="cluster-traces">cluster traces:</h3> <p><a href="https://tianchi.aliyun.com/dataset/6287">Alibaba</a></p> <p><a href="https://github.com/alibaba/clusterdata">Alibaba</a></p> <p><a href="https://github.com/Azure/AzurePublicDataset">Azure</a></p> <p><a href="https://github.com/google/cluster-data">Google</a></p> <h3 id="serverless-traces">serverless traces:</h3> <p><a href="https://github.com/alibaba/clusterdata">Alibaba</a></p> <p><a href="https://github.com/sir-lab/data-release">Huawei</a></p> <p><a href="https://github.com/Azure/AzurePublicDataset">Azure</a></p> <h2 id="related-techniques">Related Techniques</h2> <h3 id="virtualization-techniques">Virtualization Techniques</h3> <h3 id="resource-contention-and-resource-isolation">Resource Contention and Resource Isolation</h3> <h3 id="observability">Observability</h3> <p><a href="https://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html">CPU Utilization is Wrong</a></p> <p><a href="https://www.brendangregg.com/usemethod.html">USE Method</a></p> <h3 id="hypervisors-scheduler">Hypervisor’s Scheduler</h3> <p>vCPU</p> <p>vCPU overcommitment</p> <h2 id="references">References</h2> <p>Cloud Computing Models: https://aws.amazon.com/types-of-cloud-computing/</p> <p>Firecracker: Lightweight Virtualization for Serverless Applications: https://aws.amazon.com/cn/blogs/china/deep-analysis-aws-firecracker-principle-virtualization-container-runtime-technology/</p>]]></content><author><name></name></author><category term="academic"/><category term="cloud"/><category term="VM"/><category term="&quot;resource"/><category term="management&quot;"/><summary type="html"><![CDATA[Cloud computing keeps growing and provides many kinds of products for various workloads. Cloud providers and academic researchers focus on how to provide the given services with less cost, that is more efficiently. Numerous works focus on improving significant components like resource allocation, instance placement, resource harvesting and so on. Specifically, the development of AI promotes the exploration of AI for systems.]]></summary></entry><entry><title type="html">A Survey of Research on Microservices</title><link href="https://thuzxj.github.io/blog/2024/microservices/" rel="alternate" type="text/html" title="A Survey of Research on Microservices"/><published>2024-12-01T00:00:00+00:00</published><updated>2024-12-01T00:00:00+00:00</updated><id>https://thuzxj.github.io/blog/2024/microservices</id><content type="html" xml:base="https://thuzxj.github.io/blog/2024/microservices/"><![CDATA[<h2 id="introduction-of-microservice">Introduction of Microservice</h2> <p>Microservice architecture splits complex monolithic applications into multiple smaller, independent services. Microservices are loosely coupled and can be developed, deployed, and scaled independently. They collaborate through calling well-defined APIs with RPC, HTTP, or message queues.</p> <h3 id="technology-stack">Technology Stack</h3> <h4 id="hosting">Hosting</h4> <ul> <li>Container (e.g., Docker, containerd): Resource isolation</li> <li>Kubernetes: Orchestration</li> </ul> <h4 id="communication">Communication</h4> <ul> <li>service mesh (e.g., Istio, Linkerd): Traffic management, security, observability</li> <li>RPC (e.g., gRPC, Thrift)</li> <li>Message queue (e.g., Kafka, RabbitMQ)</li> <li>RESTful API</li> </ul> <h4 id="observability">Observability</h4> <ul> <li>Tracing (e.g., Jaeger, Zipkin, OpenTelemetry, Google Dapper)</li> </ul> <h2 id="research-topics">Research Topics</h2> <p>As microservices have multiple advantages, they also bring challenges, such as the complexity and overhead introduced by the communication between services. However, the decoupling of services enables us to perform fine-grained management of services and networks. The following are some research topics in microservices.</p> <h3 id="resource-management">Resource management</h3> <p>Kubernetes enables the autoscaling of the services. Vertical scaling changes the size of the resources of a single instance, such as the CPU and memory allocation of the container, while horizontal scaling changes the number of instances. The widely-used simple autoscaling algorithm needs the users to configure the range of vertical or horizontal scaling and refers to the CPU and memory usage of the services or other custom metrics to make decisions. The autoscaling algorithm helps the service adjust to dynamic or unpredictable workloads. When the workload is low, it can allocate fewer resources. When the workload increases, it can allocate more resources automatically to handle the request spikes.</p> <p>However, the decisions of autoscaling are only aware of single services, rather than the SLO of the requests and the resource usage of the whole service. One whole service can be presented as a DAG. One request can be processed by the services in parallel or in serial. The latency of the requests is the sum of the latency of each service layer in the process.</p> <p>What’s more, the configurations of the microservices are too complex for users. Users only know their SLO when deploying the services, and don’t know the SLO of each service, even the suitable resource allocation for each service.</p> <p>The basic problem is how to save as many resources as possible while guaranteeing the SLO of the service. A series of research works have been done to solve the related problems.</p> <h4 id="methodology">Methodology</h4> <p>The basic methodology includes three components. The first component involves exploring the observability of services, which provides insights into their current status. For example, leveraging new monitoring metrics to know the status more clearly, like using run queue length to guess the waiting task number (SHOWAR), and using gateway network traffic to guess the current request number (Nodens).</p> <p>The second one is the profiling and modelling of the services to predict their performance in different conditions. This component bridges the gap between the concerned performance metrics that we want to optimize, the workloads we need to handle, and the resource allocation that we can control. For each service, we can collect the data points online or offline, and model them with simple functional relationships (Cilantro, Erms). A performance model is not always necessary, as it can be replaced by a feedback-based mechanism.</p> <p>The third one is the scheduler to solve the optimization problem, that is reducing the resource usage in the constraints of guaranteeing SLO. As microservices give complex and huge action space, many works use neural networks, especially Deep Reinforcement Learning (FIRM, AWARE, Autothrottle). The DL methods have potential to solve complex strategy problems without artificial design. There are also non-DL algorithms to reach the goals (Cilantro, Erms, Derm). These methods introduce more expert knowledges of autoscaling.</p> <h4 id="evaluations">Evaluations</h4> <p>The evaluation of the performance of these works is challenging. Due to the importance of the SLO and the potential side effects of adopting new methods, these studies typically experiment with dedicated experimental systems. The experimental systems always include microservice benchmarks and load generators simulating the real load traces, running on several hosts.</p> <h4 id="comments">Comments</h4> <p>These works give us valuable insights into the resource management of microservices. They consider the QoS of services and propose various methods to manage resources efficiently.</p> <p>However, some disadvantages still hinder the practical application of these methods. Here are some of them:</p> <ol> <li><strong>The complexity of the system.</strong> These methods always give a redesign of every component in the scheduler for slightly different goals, thus these methods are not compatible with each other. Moreover, compared to the potential resource savings, the cost of implementing complex algorithms may outweigh the benefits. If we want to gain the advantages of several systems, the combined system needs to be designed with effort and will be much more complex.</li> <li><strong>The tradeoff of saving resources and throttling the services.</strong> Where do the saved resources come from? Part of them are from the higher resource utilization. Another part of them is from the throttling of services. Because the target is set to reduce SLO violations, the real latencies of the services are ignored if they satisfy the SLO. Thus, the average latency of the services under these schedulers is higher because some services are throttled to save resources.</li> <li><strong>The difficulty of proving the effectiveness of the methods.</strong> The evaluation of the methods is challenging and current evaluations are not very convincing. The experimental systems evaluate the methods, which are much simpler than the real-world systems. Their generalizability to microservices with different designs, scale and dynamic changes, can not be evaluated. In particular, the DL models’ low explainability limits their further usage in production because of the possible unexpected outputs.</li> <li><strong>The ignorance of exploring the lower-level details of the services.</strong> The latency of the services, the basis of SLO, needs more inspection. The latency contains the waiting time in the running queue, the program processing time, the network latency and so on. To have a further understanding of microservices, besides experiments, we need more explanations from the viewpoint of queue theory, probability theory, OS scheduling, the host network and so on.</li> <li><strong>The kinds of considered resource are too few.</strong> Most of these works only consider the CPU usage, ignoring the imfluence of memory, network and so on.</li> <li><strong>To be Continued.</strong></li> </ol> <h4 id="papers">Papers</h4> <ul> <li>ATOM: Model-Driven Autoscaling for Microservices (ICDCS’19)</li> <li>PARTIES: QoS-Aware Resource Partitioning for Multiple Interactive Services (ASPLOS’19)</li> <li>GrandSLAm: Guaranteeing SLAs for Jobs in Microservices Execution Frameworks (EuroSys’19)</li> <li>FIRM: An Intelligent Fine-grained Resource Management Framework for {SLO-Oriented} Microservices (OSDI’20)</li> <li>SHOWAR: Right-Sizing And Efficient Scheduling of Microservices (SoCC’21)</li> <li>SINAN: ML-based and QoS-aware resource management for cloud microservices (ASPLOS’21)</li> <li>ORION and the Three Rights: Sizing, Bundling, and Prewarming for Serverless DAGs (OSDI’22)</li> <li>Erms: Efficient Resource Management for Shared Microservices with SLA Guarantees (ASPLOS’23)</li> <li>Cilantro: Performance-Aware Resource Allocation for General Objectives via Online Feedback (OSDI’23)</li> <li>Nodens: Enabling Resource Efficient and Fast {QoS} Recovery of Dynamic Microservice Applications in Datacenters (ATC’23)</li> <li>AWARE: Automate Workload Autoscaling with Reinforcement Learning in Production Cloud Systems (ATC’23)</li> <li>Autothrottle: A Practical Bi-Level Approach to Resource Management for SLO-Targeted Microservices (NSDI’24)</li> <li>Derm: SLA-aware Resource Management for Highly Dynamic Microservices (ISCA’24)</li> <li>Atlas: Hybrid Cloud Migration Advisor for Interactive Microservices (EuroSys’24)</li> </ul> <h3 id="network-performance">Network performance</h3> <p>Microservice architecture introduces more network communication between services. Network communications introduce more overhead than function calls in monolith applications, including the inter-node and intra-node network overhead. If a sidecar mechanism is used, the network overhead will be greater. Thus the average overall latency of the service is higher.</p> <p>Placing services with close relationships on the same host can reduce inter-node network traffic and latency. However, it may destroy the independence of the services, which is one of the principle of microservice architecture.</p> <p>Reducing the host network overhead as much as possible is also a promising direction. Kernel bypass technologies have been applied to RPC.</p> <h4 id="papers-1">Papers</h4> <ul> <li>A Cloud-Scale Characterization of Remote Procedure Calls (SOSP’23)</li> <li>Remote Procedure Call as a Managed System Service (NSDI’23)</li> <li>MuCache: A General Framework for Caching in Microservice Graphs (NSDI’24)</li> <li>HydraRPC: RPC in the CXL Era (ATC’24)</li> </ul> <h3 id="configuration-tuning">Configuration tuning</h3> <p>The configuration space of microservice is huge, thus it is meaningful to build tools to explore the configuration automatically and easily.</p> <h4 id="papers-2">Papers</h4> <ul> <li>Blueprint: A Toolchain for Highly-Reconfigurable Microservices (SOSP’23)</li> <li>OPTIMUSCLOUD: Heterogeneous Configuration Optimization for Distributed Databases in the Cloud (ATC’19)</li> <li>μTune: Auto-Tuned Threading for OLDI Microservices (OSDI’18)</li> </ul> <h3 id="tracing">Tracing</h3> <p>Tracing of the request processing in the microservices is important for extracting dependencies, troubleshooting and performance analysis.</p> <p>Current tracing systems like OpenTelemetry require modification of the application code to actively report the request information and timestamps.</p> <h4 id="papers-3">Papers</h4> <ul> <li>Network-Centric Distributed Tracing with DeepFlow: Troubleshooting Your Microservices in Zero Code (SigComm’23)</li> <li>CRISP: Critical Path Analysis of Large-Scale Microservice Architectures (ATC’22)</li> <li>The Benefit of Hindsight: Tracing Edge-Cases in Distributed Systems (NSDI’23)</li> </ul> <h3 id="fault-localization">Fault localization</h3> <p>This field focuses on using the relationships between services to locate the position of the performance or logic problem. The unique problem in microservices is that one fault in a service can spread in the call graph and cause multiple faults in related services, thus localizing the root causes is challenging.</p> <h4 id="comments-1">Comments</h4> <p>Personally speaking, without experience in production microservices, current fault localization works don’t convince me of their motivation about the complexity of finding where the root causes are located. As the model of web services is relatively simple, the status of each service, such as workload overwhelming, resource contention and degration caused by other services, can be inferred through the metrics of the services, including request number, resource usage, response latency. Judging whether the performance problem is caused by the service itself or the other services seems not difficult.</p> <h4 id="papers-4">Papers</h4> <ul> <li>Sage: Practical &amp; Scalable ML-Driven Performance Debugging in Microservices (ASPLOS’21)</li> <li>Murphy: Performance Diagnosis of Distributed Cloud Applications (Sigcomm’23)</li> <li>Explainit! – a declarative root-cause analysis engine for time series data. (SIGMOD’19)</li> </ul> <h3 id="simulator-of-microservices">Simulator of microservices</h3> <p>Simulation is an important tool for understanding the performance of microservices. However, currently there are few actively maintained simulators for microservices.</p> <h4 id="papers-5">Papers</h4> <ul> <li>PerfSim: A Performance Simulator for Cloud Native Microservice Chains</li> <li>μqSim: Enabling Accurate and Scalable Simulation for Interactive Microservices</li> </ul> <h3 id="demo-microservices-for-research">Demo microservices for research</h3> <ul> <li><a href="https://github.com/delimitrou/DeathStarBench">DeathStarBench</a></li> <li><a href="https://github.com/FudanSELab/train-ticket">Train-Ticket</a></li> <li><a href="https://github.com/microservices-demo">Microservice-demo</a></li> </ul>]]></content><author><name></name></author><category term="academic"/><category term="microservice"/><category term="cloud"/><summary type="html"><![CDATA[A Survey of Research on Microservice]]></summary></entry><entry><title type="html">Deterministic Compilation by eBPF (基于eBPF的确定性编译工具)</title><link href="https://thuzxj.github.io/blog/2023/deterministic-build-by-eBPF/" rel="alternate" type="text/html" title="Deterministic Compilation by eBPF (基于eBPF的确定性编译工具)"/><published>2023-07-03T00:00:00+00:00</published><updated>2023-07-03T00:00:00+00:00</updated><id>https://thuzxj.github.io/blog/2023/deterministic-build-by-eBPF</id><content type="html" xml:base="https://thuzxj.github.io/blog/2023/deterministic-build-by-eBPF/"><![CDATA[<h2 id="1-关于inclavare-containers">1. 关于Inclavare Containers</h2> <p>本项目和Inclavare Container社区在阿里巴巴编程之夏项目中合作完成，<a href="https://github.com/inclavare-containers/deterministic-builds">项目地址</a>。</p> <p>Inclavare是<code class="language-plaintext highlighter-rouge">enclave</code>的拉丁语源，它是机密计算领域中一种为了保护用户数据，将用户的敏感工作负载与不受信任的、不可控的 基础设施隔离的技术。</p> <p>Inclavare Container是一种从硬件辅助可信执行环境（TEE）中启动受保护容器的安全容器运行时。</p> <h2 id="2-项目介绍">2. 项目介绍</h2> <p>确定性编译（Deterministic Compilation），或者说可复现构建（Reproducible Builds），是指从相同的源代码中编译出相同的二进制文件的技术。它在软件供应链的安全以及管理中有重要作用。</p> <p>免费与开源软件的源代码可以供所有人来检查，但是大多数软件都是预编译分发的，很难确认编译出的二进制文件是否与源代码对应，而没有引入只隐藏于二进制文件的后门或漏洞。确定性编译技术目标是搭建一个与编译时间、机器、文件名等无关的编译环境，让第三方可以方便地验证二进制文件是否由指定版本的源代码编译而成。</p> <p>同时在二进制文件的管理中，如果需要对二进制文件进行存储管理，那么最好不要让二进制文件中存储会随着环境改变的时间戳、文件路径等信息，以形成完全相同的二进制文件。而确定性编译技术可以免除编译器引入这些不确定因素。</p> <p>检查两个二进制文件是否相同的一个简单的方法是消息摘要（message digest），包括MD5，SHA系列算法等。</p> <p>已有的确定性编译方案通过对编译器进行配置、ptrace拦截系统调用实现。而本项目希望实现基于eBPF的确定性编译系统。eBPF是Linux内核提供的在内核中运行沙箱程序的技术，允许开发者在不改动内核代码的同时对Linux内核的安全、网络、监控等功能进行扩展。Kprobe是Linux内核提供的对内核内任意函数（包括系统调用）进行跟踪探测的机制，可以在指定的函数调用时、任意指令处与函数返回时执行额外的程序。Linux同样提供了很多tracepoint的tracing机制。eBPF可以把代码挂载到Kprobe机制上，相比于直接开发Kprobe模块拥有eBPF提供的安全保障。</p> <p>使用eBPF来监控编译器会引入不确定因素的系统调用进行监控，并修改其返回值，我们可以开发出一个对编译器完全透明的确定性编译工具，只需要在后台运行eBPF程序，不需要在使用编译器时添加额外的配置与指令，也不会影响除了编译器与其他编译所需工具之外的其他进程。</p> <p>本项目我们的主要目标是让工具可以实现Linux内核的确定性编译。</p> <h2 id="3-开发情况">3. 开发情况</h2> <h3 id="编译中的不确定因素">编译中的不确定因素</h3> <p>首先我们需要定位编译器引入的不确定因素，以及它们所对应的系统调用。经过调研与实验，编译器在运行中主要会受到时间、随机数、文件系统等影响，在字符串、符号名、可执行文件时间戳等包含不确定因素。</p> <h4 id="方案">方案</h4> <p>我们没有去阅读编译器代码，而是采用以下方法进行调查：一方面我们收集一些常见的不确定性因素（如宏定义等），进行实验并跟踪系统调用；一方面我们通过编译Linux内核查看编译出的二进制文件中存在哪些不确定性。</p> <p>Linux内核的编译中，我们使用相同版本的编译器、相同的配置文件、相同的Linux内核源码版本，分别在不同的时间、不同的Linux系统、不同的文件路径上进行编译，检查不同情况下编译出的二进制文件vmlinux的区别。</p> <h4 id="工具">工具</h4> <p>strace可以用来监控编译器的系统调用。由于gcc编译器的预处理进行是在子进程中的，所以strace使用时需要使用<code class="language-plaintext highlighter-rouge">--follow-forks</code>或<code class="language-plaintext highlighter-rouge">-f</code>选项。</p> <p>二进制文件的相关工具，用于比较二进制文件的可以使用xxd与diff（或colordiff、cmp）等配合，查看二进制文件内容的有strings、nm、readelf、objdump等，二进制文件的GUI编辑器有010editor等。</p> <h4 id="结果">结果</h4> <p>我们发现以下几种编译不确定性的来源：</p> <h5 id="1">1</h5> <p>gcc编译器提供了一些预先定义好的宏定义，在预处理阶段会进行宏定义展开与include展开等工作。其中<code class="language-plaintext highlighter-rouge">__DATE__</code>，<code class="language-plaintext highlighter-rouge">__TIME__</code>分别可以展开为编译时的日期与时间的字符串。<code class="language-plaintext highlighter-rouge">__TIMESTAMP__</code>与<code class="language-plaintext highlighter-rouge">__FILE__</code>可以展开为被编译的文件的最后一次修改时间戳和相对路径的字符串。</p> <h5 id="2">2</h5> <p>此外，在gcc中开启LTO优化时，会在.o文件中生成随机的符号名称，使用了系统的random相关系统调用，这会影响到.o文件的确定性。</p> <h5 id="3">3</h5> <p>在编译与比较Linux kernel中，发现vmlinux中有一个字符串是编译信息的记录，有编译此内核的Linux版本、用户名与机器名、gcc版本、时间戳、内核功能选项等。经调查，在内核安装后<code class="language-plaintext highlighter-rouge">/proc/version</code>会提供此版本信息；在编译时<code class="language-plaintext highlighter-rouge">scripts/mk_compile_h</code>会在<code class="language-plaintext highlighter-rouge">compile.h</code>中获取并在代码中生成各种信息，在编译机器上使用了<code class="language-plaintext highlighter-rouge">date</code>, <code class="language-plaintext highlighter-rouge">whoami</code>, <code class="language-plaintext highlighter-rouge">uname</code>等指令。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Linux version 5.18.11-051811-generic (kernel@gloin) (gcc (Ubuntu 11.3.0-4ubuntu1) 11.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38.50.20220629) #202207121541 SMP PREEMPT_DYNAMIC Tue Jul 12 15:47:28 UTC 2022
</code></pre></div></div> <p>我们还发现二进制文件中有5处随机数的差异。在用LD_PRELOAD方法简单拦截libc中相关时间函数后，发现时间戳与随机数都变成相同的值，说明内核编译中产生随机数与时间相关。</p> <h3 id="确定性编译工具">确定性编译工具</h3> <p>我们使用libbpf，使用C语言进行eBPF程序的开发。eBPF的开发工具还有Bpftrace，bcc等，但是尝试在这些框架下实现同样的修改系统调用功能时并不会获得预期的行为，具体原因还需要学习与调查。</p> <h4 id="ebpf修改系统调用的返回值">eBPF修改系统调用的返回值</h4> <p>与ptrace、seccomp等不同的是，eBPF并不允许直接修改函数的参数、返回值等。但是eBPF提供了一个<code class="language-plaintext highlighter-rouge">bpf_probe_write_user</code>函数，该函数可以传入一个用户空间地址（<code class="language-plaintext highlighter-rouge">void*</code>类型）dst和一个eBPF程序地址（<code class="language-plaintext highlighter-rouge">void*</code>类型）src以及一个u32类型的长度参数，它可以将src buffer的内容写入到用户空间，达到修改用户空间内存的目的。而一部分系统调用传入一个指向结构体的指针，调用者期待从结构体中获得函数返回的数据，这个地址也会被kprobe传入eBPF程序中，那这个结构体里的返回结果就可以被修改，如<code class="language-plaintext highlighter-rouge">gettimeofday</code>，以<code class="language-plaintext highlighter-rouge">struct timeval *tv, struct timezone *tz</code>两个参数返回具体的值，函数返回值只是0与-1的状态码。同样的，如果系统调用传入的参数是一个字符串，那么这个字符串也可以被修改成一个不比原来长的另一个字符串。很遗憾函数的返回值仍然不能被修改，但是能修改结构体中的结果对实现确定编译的目标已经足够了。而如果系统调用没有传入一个指针，那么eBPF程序对修改这个函数就无能为力了，比如<code class="language-plaintext highlighter-rouge">time</code>，直接以<code class="language-plaintext highlighter-rouge">time_t</code>类型作为返回值。</p> <p>离可以修改系统调用只剩一步之遥了：eBPF的进入与退出hook点都只能获取到部分上下文信息，进入函数的hook点可以获得函数参数，包括结构体指针，但是不能在此时修改结构体，因为会被后面的函数逻辑再次修改；退出函数的hook点是修改结果的时机，但是只提供了函数返回值，没有提供结构体指针。这时就需要使用到eBPF的MAP（相当于eBPF程序各个地方都可以访问到的全局key value存储），实现进入函数向退出函数传递指针数据，我们使用进入与退出函数都可以获得的tid（对于每一次目标函数调用都是唯一的）作为key，传递的指针作为value，这样就使得退出函数也能获得结构体指针。</p> <p>所以修改系统调用的流程是：</p> <ol> <li>在进入Hook函数中，通过进程名过滤掉不需要的进程，向map存储&lt;tid, arg0&gt;</li> <li>在退出Hook函数中，通过进程名过滤掉不需要的进程，然后通过tid查询map获得arg0</li> <li>构建假的返回值，并使用bpf_probe_write_user修改用户态内存</li> </ol> <p>最终我们使用这种方法可以修改<code class="language-plaintext highlighter-rouge">openat</code>,<code class="language-plaintext highlighter-rouge">newfstatat</code>,<code class="language-plaintext highlighter-rouge">read</code>,<code class="language-plaintext highlighter-rouge">getrandom</code>,<code class="language-plaintext highlighter-rouge">gettimeofday</code>,<code class="language-plaintext highlighter-rouge">clock_gettime</code>，<code class="language-plaintext highlighter-rouge">uname</code>等系统调用，去除文件系统、时间、随机数、主机带来的不确定性。</p> <h4 id="vdso的处理">vDSO的处理</h4> <p>在使用strace date等命令，对时间相关的系统调用进行分析时，会发现<code class="language-plaintext highlighter-rouge">time</code>，<code class="language-plaintext highlighter-rouge">gettimeofday</code>，<code class="language-plaintext highlighter-rouge">clock_gettime</code>并不会出现在strace的结果中，使用eBPF也没有办法被触发。这是因为Linux的<code class="language-plaintext highlighter-rouge">vDSO</code>机制，它把time相关的系统调用结果映射到内存中，在调用这些系统调用时直接从用户内存中读取结果，可以减少用户态与内核态的切换开销，做到快速系统调用。vDSO在Linux运行中是默认开启的，因此在使用工具前我们需要在启动选项中把它关闭。</p> <h4 id="与ld_preload配合">与LD_PRELOAD配合</h4> <p>由于eBPF程序无法修改<code class="language-plaintext highlighter-rouge">time</code>系统调用的返回值，我们需要使用另外的方法修改它。<code class="language-plaintext highlighter-rouge">time</code>系统调用被libc中的<code class="language-plaintext highlighter-rouge">time</code>函数使用，所以我们可以使用<code class="language-plaintext highlighter-rouge">LD_PRELOAD</code>的方法，在用户态把libc中的<code class="language-plaintext highlighter-rouge">time</code>函数替换掉。但是这样就需要在环境变量中指定LD_PRELOAD的so文件，或是在系统配置文件<code class="language-plaintext highlighter-rouge">/etc/ld.so.preload</code>中指定所有可执行文件的preload路径，无法做到自动拦截指定的编译相关进程的调用。而通过对<code class="language-plaintext highlighter-rouge">LD_PRELOAD</code>机制的系统调用进行分析，我们同样可以通过拦截系统调用的方式，让不同进程的读到的<code class="language-plaintext highlighter-rouge">/etc/ld.so.preload</code>不同，只对编译相关进程加载preload文件。</p> <h4 id="结果-1">结果</h4> <p>以date命令为例，使用modify_time可以使输出的时间为固定值（在编译前在一个头文件中配置）：</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">date</span> <span class="c"># normal</span>
Mon Oct 17 04:25:13 PM CST 2022
<span class="nv">$ </span><span class="nb">sudo</span> ./modify_time &amp;
<span class="nv">$ </span><span class="nb">date</span> <span class="c"># modified</span>
Mon Oct 17 04:26:25 PM CST 2022
</code></pre></div></div> <p>以下为eBPF程序的log：</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span><span class="nb">sudo cat</span> /sys/kernel/debug/tracing/trace_pipe
			&lt;...&gt;-816502  <span class="o">[</span>006] d..31 5707624.022076: bpf_trace_printk: <span class="o">[</span>sys_exit_clock_gettime] OVERWRITING struct timespec64 at     00000000c626f924 from <span class="o">(</span>1665995173, 362091123<span class="o">)</span> to <span class="o">(</span>1659312000, 0<span class="o">)</span>
           &lt;...&gt;-816502  <span class="o">[</span>006] d..31 5707624.022077: bpf_trace_printk: <span class="o">[</span>sys_exit_clock_gettime] RESULT 0
</code></pre></div></div> <h3 id="测试工具">测试工具</h3> <p>为了在多个环境中测试编译确定性，我们基于shell脚本与docker实现了部分编译自动配置与编译的功能，如C语言宏定义的编译与kernel源码的配置与编译。</p> <h2 id="参考资料">参考资料</h2> <p>eBPF and syscall:</p> <ul> <li><a href="https://stackoverflow.com/questions/43003805/can-ebpf-modify-the-return-value-or-parameters-of-a-syscall">Can eBPF modify the return value or parameters of a syscall?</a></li> <li><a href="https://embracethered.com/blog/posts/2021/offensive-bpf-libbpf-bpf_probe_write_user/">Offensive BPF: Understanding and using bpf_probe_write_user</a></li> <li><a href="https://stackoverflow.com/questions/38103583/capture-vdso-in-strace">Capture vDSO in strace</a></li> <li><a href="https://lists.linuxfoundation.org/pipermail/iovisor-dev/2017-May/000740.html">[iovisor-dev] kprobe modify syscall</a></li> </ul> <p>deterministic build:</p> <ul> <li><a href="https://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html">Deterministic builds with clang and lld</a></li> <li><a href="https://blog.conan.io/2019/09/02/Deterministic-builds-with-C-C++.html">An introduction to deterministic builds with C/C++</a></li> </ul>]]></content><author><name></name></author><category term="projects"/><category term="eBPF"/><category term="deterministic-build"/><summary type="html"><![CDATA[Deterministic Compilation by eBPF (基于eBPF的确定性编译工具)]]></summary></entry></feed>