Skip to content
Istemi Ekin Akkus edited this page Jul 10, 2020 · 2 revisions

Key ideas

Here are a few of the key ideas that KNIX utilizes to provide fast function startups and interactions as well as support for application sessions.

1. Application-level sandboxes

The idea behind KNIX's sandboxing is simple: Isolating different functions of the same application with the same mechanisms used to isolate functions of different tenants seems unnecessary. KNIX relaxes this isolation requirement and utilizes separate processes in a single container for each function of an application. This isolation mechanism enables KNIX to start concurrent function instances fast by using process forking in contrast to starting concurrent containers to handle each request. As a result, applications running on KNIX are isolated via stronger mechanisms (e.g., containers) and function instances of the same application are isolated via OS processes.

2. Local shortcuts for function interactions

An application consisting of multiple functions is inevitably going to utilize interactions among different functions. For example, these interactions can be part of a workflow execution that requires the triggering and execution of several functions. Because KNIX chooses to place these different functions as separate processes in the same container, it is in a unique position to enable them to take advantage of locality. To do so, KNIX provides a local queue service for each application, such that functions of a workflow can trigger each other locally. This approach enables KNIX to provide very low function interaction latencies -- the time it takes between the end of a function execution and the start of the next function -- that are in the order of single-digit milliseconds.

3. Hierarchical storage

Similar to creating local shortcuts for funtion interactions via the local queue service, the hierarchical data layer achieves the same goal for sharing data among different functions. Functions of an application running on a host can share data utilizing the local data layer service, whereas riak provides a persistent storage that is globally accessible by the functions that might be running on different hosts (e.g., as part of another sandbox instance created for scalability). KNIX coordinates the different layers, whereby any item written on the local data layer is asynchronously sent to the global layer. While this applies to key-value storage, work is going on providing the same principle for CRDTs (i.e., maps, sets, counters).

4. Session functions

Although a majority of serverless computing scenarios may involve stateless functions that execute for a short amount of time, there are times when externalizing the state of the function at the end of an execution (i.e., to storage) and later reinitializing the state at the beginning of the next execution (i.e., from storage) might simply add too much overhead (even though KNIX provides a hierarchical storage with a local data layer that reduces this overhead, sometimes applications might require more performance). Imagine an application with a user session that is time critical to maintain. To facilitate such applications, KNIX provides stateful session functions that are long-running and addressable via the same event message bus that is used for stateless functions. Session functions can run in a loop and/or wait for control messages in a blocking or non-blocking way, while at the same time continuing to keep their state in memory and updating it, so that any additional events can be processed at high performance using that state. KNIX provides developers to instantiate, manage and control such functions. When session function instances are no longer needed (e.g., at the end of an application session), they are destroyed, so that the application can match its demand for resources to the actual load it receives (i.e., the number of sessions), preserving the benefits of serverless computing.