Created
March 15, 2018 15:40
-
-
Save cgrand/8a57d5761d2c5c5ab5dbec25d5d0c823 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn lambda-model | |
"Crude model. rps is requests per second, len is a function that returns the | |
execution length in seconds, until is the number of seconds to run the simulation, | |
spawn is a function returning the number of ping sub requests, duty is the max age | |
for a container, keep-alive is the number of seconds before decommissioning a | |
container. | |
Returns a map with: the number of user perceived cold starts and the number of | |
billable seconds." | |
[{:keys [rps len until spawn duty keep-alive] | |
:or {rps 10 | |
len (constantly 1) | |
spawn (constantly 0) | |
duty (* 4 60 60) | |
keep-alive (* 30 60) | |
until (* 24 60 60)}}] | |
(let [n (Math/floor (* 0.1 rps)) | |
pn+1 (- (* 0.1 rps) n)] | |
(loop [t 0.0 pings 0 containers nil stats {:s 0 :user-colds 0}] | |
(if (< t until) | |
(let [containers (into #{} | |
(comp | |
(remove #(and (<= (:end %) t) | |
(< (+ (:boot %) duty) t))) | |
(remove #(and (<= (:end %) t) | |
(< (+ (:end %) keep-alive) t)))) | |
containers) | |
runnables (sort-by :end > (filter #(<= (:end %) t) containers)) ; lru | |
reqs (cond-> n (< (rand) pn+1) inc) ; not probabilistic enough | |
m (+ reqs pings) | |
next-pings (reduce + (repeatedly reqs spawn)) | |
warms (take m runnables) | |
others (reduce disj containers warms) | |
colds (for [id (range 0 (- m (count warms)))] | |
{:boot t :end t | |
:id id}) | |
ready (shuffle (concat warms colds)) | |
started (-> [] | |
(into (map #(assoc % :end (+ t (len)))) (take reqs ready)) | |
(into (map #(assoc % :end (+ t 0.1))) (drop reqs ready))) | |
s (transduce (map #(- (:end %) t)) + started) | |
containers (into others started) | |
user-colds (count (filter #(= (:end %) (:boot %)) (take reqs ready)))] | |
(recur (+ t 0.1) next-pings containers | |
(-> stats (update :user-colds + user-colds) (update :s + s)))) | |
stats)))) | |
=> (lambda-model {:until (* 24 3600) | |
:len #(+ 0.8 (rand)) | |
:rps 5}) | |
{:s 561520.3102497417, :user-colds 98} | |
; with one "ping" generated for 50% of user requests | |
=> (lambda-model {:until (* 24 3600) | |
:len #(+ 0.8 (rand)) | |
:spawn #(if (< (rand) 0.5) 1 0) | |
:rps 5}) | |
{:s 582463.0752570062, :user-colds 54} | |
; the nuber of perceived cold starts is almost divided by 2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment