fn
fn copied to clipboard
clamp down user API around container system parameters to fix around memory
at present, we allow a user to set cpu, memory, and tmpfs_size on a given function (tba 'network'). this allows variable amounts for any of those given parameters where they are independent of one another. quite simply, this issue proposes to base the settings for any other system resources that exist currently or in the future off of memory alone. first, illustrated with an example (these are not in any way prescriptive):
- 128MB RAM, 500mCPU, 256MB tmpfs, 100Mb/s network
- 256MB RAM, 1000mCPU, 512MB tmpfs, 200Mb/s network
- ... up to some N cap of RAM, say 2GB or something.
where a user would only set and/or see the memory setting, and all of the other settings would get applied under the hood for that function (not visible to the user via API). part of the work to do this / make this capable has gone in https://github.com/fnproject/fn/pull/1065 with the current API intact, this aims to round this out a little more.
lambda's copyright around this is as follows, if this helps to clarify:
You only specify the amount of memory you want to allocate for your Lambda function. AWS Lambda allocates CPU power proportional to the memory by using the same ratio as a general purpose Amazon EC2 instance type, such as an M3 type. For example, if you allocate 256 MB memory, your Lambda function will receive twice the CPU share than if you allocated only 128 MB. You can update the configuration and request additional memory in 64 MB increments from 128MB to 3008 MB.
benefits:
- the user api would be very simple, only exposing memory. this has been one particular concern where in a setting with certain shape 'tiers' (similar to above), if a user sets one setting, does this mean we should adjust the other settings to more closely fit a valid shape based on a certain parameter (i.e. do we need to do minimum/maximum calculation to fit) or do we error, ignore certain fields, etc etc. this is much more straightforward than what is possible now if a service provider wants to provide an equivalent API to the OSS fn API, where the service provider would need middleware to provide some of the above outlined logic.
- configuring these settings for a service provider could be as simple as setting 'memory_interval', such as 128MB shown above, a 'max_memory' where the interval would cap out at, a 'factor' for all of or each setting and the 'interval' for cpu, tmpfs, network, etc. these could be done as simply as having environment variables, or in another way, but is not particularly challenging to plumb. it would also be possible to have some kind of table config for shapes, or even an admin API to hook this up. this particular point will have to get sorted out should this feature go through.
- a service provider can magically change the settings behind the scenes without any notice through the API. for example, if new VM shapes come in that allow splitting up a VM into the same memory sized chunks with double the CPU or network bandwidth, et voila: there's no documentation to update this amount in the API settings or go update across all user functions, they'll just get the extra juice. or when we decide to give users real disks instead of tmpfs to write things to, they won't have to futz with another setting for disk to go next to tmpfs size, we can just move them onto disks / deprecate tmpfs / whatever.
- aligns with what competitors are doing and provides a familiar, understandable user experience
cons:
- lack of flexibility for functions shaping, most functions will not uniformly use 128MB of RAM and .5mCPU and 100Mb/s network, they'll likely be bound on one of these and could in theory lower the needs for the things they are not bound on, and in theory a service provider could more efficiently pack things that are more bound by those other things onto those machines. while this sounds nice, it requires a lot of vertical integration across the product and to date only Google functions seems to have a flexible billing model based off of memory and cpu usage, opposed to microsoft and lambda which bill by gigabytes of memory used over function duration. maybe the Google billing model is worth discussion as this does have implications across the product and may be flexible enough for our needs as well as other models.
- users are unaware of how much of the other stuff they're getting (potentially), like CPU, disk, . this is notably also in the benefit section for different reasons.
cc @shaunsmith @skinowski
+1
Note that Google Functions may bill for both GB and GHz but the user only selects GBs. The relationship between GBs and GHz is fixed. IMHO this is simply pricing obfuscation.
My thinking here is that CPU ought to somewhat configurabile/pluggable - either at the LB ingress point (i.e. one policy for all functions) or at the agent itself (policy based on specific host configuration - you get what we got, based on the host, maximise usage of specific hosts)
/tmp (we keep saying tmpfs but actualy I don't see a necessity that this is actually a memory-backed tmpfs, could be e.g. a loopback on disk) probably ought to be uniform (even if it's proportional to RAM ) across the system but also configurable as it represents a much harder constraint on the function implementation rather than CPU - when I target a particular platform I want to know how much /tmp I'm going to get.