Skip to content

Shared memory data transfer between Functions Host and Python worker #816

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 81 commits into from
Mar 24, 2021

Conversation

gohar94
Copy link
Contributor

@gohar94 gohar94 commented Feb 5, 2021

Description

Fixes Azure/azure-functions-host#6791
Moved from this PR.


PR information

  • The title of the PR is clear and informative.
  • There are a small number of commits, each of which has an informative message. This means that previously merged commits do not appear in the history of the PR. For information on cleaning up the commits in your pull request, see this page.
  • If applicable, the PR references the bug/issue that it fixes in the description.
  • New Unit tests were added for the changes made and CI is passing.

Quality of Code and Contribution Guidelines

@gohar94
Copy link
Contributor Author

gohar94 commented Feb 5, 2021

cc @goiri
Moved from the forked repo to the azure one.

Copy link
Contributor

@Hazhzeng Hazhzeng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is well documented and great work!
Ping @vrdmr as you may also want to check.

@Hazhzeng Hazhzeng marked this pull request as ready for review February 12, 2021 23:30
@gohar94 gohar94 force-pushed the gochaudh/shared_mem_data_transfer branch from 57ebbb9 to e59c6fe Compare February 18, 2021 19:22
@gohar94
Copy link
Contributor Author

gohar94 commented Mar 13, 2021

@vrdmr @goiri @Hazhzeng
Below is comparison of throughput before and after these changes.
Using the same k6 perf testing infra as run in this workflow. I will soon push the load test that I added (after my PR for the required test functions is approved).
For now, just dumping the test here below. It invokes (using the load generator) an HTTP function which will write a 256MB blob.

Results:
WITHOUT shared memory:
image

WITH shared memory:
image

~21% reduction in median and P95 time for writes of 256MB. We can do a deeper analysis to get some more data points with different sizes. Similarly, will do it for reads.

import { check } from "k6";
import { Rate } from "k6/metrics";
import http from "k6/http";
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.0.0/index.js";

var HOSTNAME = __ENV.HOSTNAME || 'localhost';
var PORT = __ENV.PORT || '80';
var PROTOCOL = __ENV.PROTOCOL || (PORT === '80' ? 'http' : 'https');

// A custom metric to track failure rates
var failureRate = new Rate("check_failure_rate");

// Options
export let options = {
    stages: [
        // Linearly ramp up from 1 to 50 VUs during first minute
        { target: 50, duration: "1m" },
        // Hold at 50 VUs for the next 3 minutes and 30 seconds
        { target: 50, duration: "3m45s" },
        // Linearly ramp down from 50 to 0 50 VUs over the last 30 seconds
        { target: 0, duration: "15s" }
        // Total execution time will be ~5 minutes
    ],
    thresholds: {
        // We want the 95th percentile of all HTTP request durations to be less than 40s
        "http_req_duration": ["p(95)<40000"],
        // Thresholds based on the custom metric we defined and use to track application failures
        "check_failure_rate": [
            // Global failure rate should be less than 1%
            "rate<0.01",
            // Abort the test early if it climbs over 5%
            { threshold: "rate<=0.05", abortOnFail: true },
        ],
    },
};

// Main function
export default function () {
    let content_size = 1024 * 1024 * 256; // 256 MB
    let no_random_input = true;
    let outfile = randomIntBetween(1,500000);
    let url = `${PROTOCOL}://${HOSTNAME}:${PORT}/api/SyncPutBlobAsBytesReturnHttpResponse?content_size=${content_size}&no_random_input=${no_random_input}&outfile=${outfile}`;
    let response = http.get(url);

    // check() returns false if any of the specified conditions fail
    let checkRes = check(response, {
        "status is 200": (r) => r.status === 200,
        "content_size matches": (r) => r.json().content_size === content_size,
    });

    // We reverse the check() result since we want to count the failures
    failureRate.add(!checkRes);
}

@gohar94
Copy link
Contributor Author

gohar94 commented Mar 15, 2021

Results for read throughput:

WITHOUT shared memory:
image

WITH shared memory:
image

Copy link
Member

@vrdmr vrdmr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second round of comments.

@vrdmr vrdmr requested a review from Hazhzeng March 17, 2021 08:39
Copy link
Member

@vrdmr vrdmr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @gohar94 for the changes. 🚢 👍🏼

Thanks, @goiri @Hazhzeng for the reviews!
FYI @AnatoliB - The PR has been reviewed by @goiri, @Hazhzeng, and me. Let me know if you have any questions. We can merge this whenever you get a chance to take a look at this.

@Hazhzeng Hazhzeng merged commit 9324efc into dev Mar 24, 2021
@Hazhzeng Hazhzeng deleted the gochaudh/shared_mem_data_transfer branch March 24, 2021 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shared memory data transfer between Functions host and out-of-proc workers for binary data
4 participants