scottdw2
Joined 17 years ago
Joined 17 years ago
1. The snippets of code you run in Lambda are called "cloud functions".
2. Lambda applications are generally event driven and stateless, which is a very functional idiom.
As other folks mentioned, however, you can use Lambda with non functional languages (like Java). So even though a Lambda application is inherently functional (small stateless functions communicating via events), you don't have to write in a functional style if you don't want to.
I'll take a look tomorrow and see if I can reproduce what you are seeing. I'm not super familiar with API gateway, so there could be some config issues over there.
If you want to discuss this more offline, feel free to contact me at "scottwis AT amazon".
Here are the details on pricing:
https://aws.amazon.com/lambda/pricing/
You get up to 1M requests / month and 400,000 GB-seconds of compute time per month.
A default lambda function uses 128 MB of ram (0.125 GB), which gives you about 3.2 M seconds of compute time (time actually spent executing requests) every month for free.
Thus if you have functions that take 500 ms on average, and use the default amount of RAM, you can process about 6.4 M requests in a month for a total bill of $1.20.
Above the free tier limits you pay $0.20 per million requests, and $0.1667 per million GB-seconds.
The pricing is fairly attractive.
If you are using "Node.js", you may be seeing slow times if you are not calling "context.done" in the correct place, or if you have code paths that don't call it.
Not calling context.done could either cause Node.js to exit, either because the node event loop is empty, or because the code times out, and Lambda kills it.
When node exits, the container shuts down, which means Lambda can't re-use the container for the next invoke and needs to create a new one. The "cold-start" path is much slower than the "warm-start" path. When Lambda is able to re-use containers, invokes will be much faster than when it can't.
Also, how are you initializing your connection to DDB? Is it happening inside your Lambda function? If you either move it to the module initializer (for Node), or to a static constructor (for Java), you may also see speed improvements.
If you initiate a connection to DDB inside the Lambda function, that code will run on every invoke. However, if you create it outside the Lambda function (again in the Module initializer or in a static constructor) then that code will only run once, when the container is spun up. Subsequent invokes that use the same container will be able to re-use the HTTP connection to DDB, which will improve invoke times.
Also, you may want to consider increasing the amount of RAM allocated to your Lambda function. The "memory size" option is badly named, and it controls more than just the maximum ram you are allowed to use. It also controls the proportion of CPU that your container is allowed to use. Increasing the memory size will result in a corresponding (linear) increase in CPU power.
One final thing to keep in mind when scaling a Lambda function is that Lambda mainly throttles on the number of concurrent requests, not on the transactions per second (TPS). By default Lambda will allow up to 100 concurrent requests.
If you want a maximum limit greater than that you do have to call us, but we can set the limit fairly high for you.
The scaling is still dynamic, even if we have to raise your upper limit. Lambda will spin up and spin down servers for you, as you invoke, depending on actual traffic.
The default limit of 100 is mainly meant as safety limit. For example, unbounded recursion is a mistake we see frequently. Having default throttles in place is good protection, both for us and for you. We generally want to make sure that you really want to use a large number of servers before we go ahead and allocate them to you.
For example, a lot of folks use Lambda with S3 for generating thumbnail images, sometimes in several different sizes. A common mistake some folks make when implementing this for the first time is to write back to the same s3 bucket they are triggering off of, without filtering the generated files from the trigger. The end result is an exponential explosion of Lambda requests. Having a safety limit in place helps with that.
In any case, if you are having trouble getting Lambda to scale, I'm happy to try and help.
If you don't need strong consistency (after a write commits, all future reads will see the write), you can use simpler replication strategies.
Redis, for example, using async replication, that is not guaranteed to succeed. A redis master may ack a write, and a subsequent read may see it, but a loss of the master before replication occurs can result in data loss. The failover is not guaranteed to contain all writes. Some times weak consistency is ok. Sometimes it's not, but eventual consistency is ok. Other times strong consistency is needed.
Raft is useful when you need strong consistency.
Raft does support membership changes (adding and removing nodes from the cluster), so it can support losing more than n / 2 - 1 nodes, just not simultaneously.
1. You don't have to round trip to every member before acking a write request, only to a majority of them.
2. If you use the right data structures for your state machine (like persistent data structures), you don't have to fully commit a write before you start the next write. That is, as long as you can quickly revert to a previously committed state (which you can with persistent data structures, it just becomes a CAS on a pointer) you can pipeline requests and batch commits. That lets you start on write n+1 using the state machine results of write n, even though write n hasn't been committed yet. You can then commit a bunch of results (n, n-1, n-2, ...) as a single batch. That does create a dependency that some write j may be rolled-back because a write i < j failed to commit, but you would have had that dependency anyways (you wouldn't have even started write i unless write j had committed). So, although latency of a single request is bounded by the time to replicate a log entry to n/2 + 1 hosts, the throughput is not bounded by the latency of a single write.
The raft paper doesn't actually say you can do this (it says things like "don't apply state machines until a transaction has been committed), but that's because it assumes arbitrary side effecting state machines. However, with some restrictions (like using persistent data structures), you can relax that requirement. Relaxing that requirement can give quite good throughput.
3. You can horizontally scale raft the same way you horizontally scale any other distributed data store: using consistent hashing. You would use a hash ring of raft clusters.
4. You can loose up to n/2 hosts from a raft cluster and it will still work.
5. Raft is "multiple servers with failover and a version clock". In fact it's "multiple servers with failover, a version clock, and strong sequential consistency".
It's not represented in head normal form, but it's still lazy.
The limitations you mentioned are not an artifact of the implementation being eager(because it's not eager), but instead are an artifact of the representation used.
You deliver some digital assets, the key to which can only be derived if a particular crypto currency transaction is performed.
But if you are delivering physical goods, there's going to be some human aspect to it.
Some human, somewhere, is going to deliver the good to some other human.
I'm not discounting the idea of automated contract enforcement. I think contract enforcement is really inefficient. Finding a way to automate it seems like it could be useful. That's the niche paypal originally filled (providing escrow services for ebay transactions). If you could find a way to automate such things, so that everywhere you currently see a "standard service" contract nowadays you had someone clicking on a button (and maybe entering a credit card number), it seems like it could be disruptive. Kind of like a Google App engine for executing contract logic.
I'm just not sure that bit coin is central to the whole thing.
The whole "free from government interference" thing is a bit of a fallacy. If the government wants to seize your bit coins, they will find a way. It may be difficult for them to manipulate the price of bit coin, and to implement wholesale theft (stealing everyone's bit coins), but seizure of a specific individual's bit coins is definitely possible. They'll find a way.
Maybe some form of contracts, like options trading, might work. Equity funding of startups might work too. Basically anything that's purely digital.
But I don't think that any contract involving physical goods can be rendered mathematically perfect.
Both have typically been handled by courts.
Contract validation is typically very "human centric". It centers on questions such as "what is a bargain?" or "is this result acceptable to the conscience (I.e. is morally acceptable)".
Contract enforcement, however, is much more formulaic. Given a valid contract, and a series of events (leading to a breach), quantify what relief would look like.
I don't think validity can be automated. It's analogous to Dijkstra's obsession with "formal verification".
However, most contracts are valid. They typically involve genuine negotiations on reasonable terms.
Assuming validation, enforcement is easily automated.
I don't think bit coin is relevant though. For automated contract enforcement any payment API will work. Wether it's bit coin, or paypal in Estonian Kroon, the important part is automation.
There's already too many apps, so preventing "over choice" isn't their goal.
The marginal cost of a virtual good is zero. Apple's ability to support apps is effectively infinite.
There are over 1M apps in the App Store.
This is not about "shelf space".
Here's an even better question: if your enemy thinks like you, talks like you, acts like you, shares your values and views the world the way you do, is he your enemy? Can he be your enemy? Why would he be your enemy?
Let's consider a central question.You espouse a belief in freedom, a nation built on liberty. Your enemy denies this, proclaims you a tyrant, and endeavors to make war against you. How do you respond?
One method undercuts your enemy's message, reaffirms your core values, and has the potential to alter and modify your enemy so that he is predisposed to be united with you.
The other affirms his message, strengths his position, and emboldens those who follow him.
This leads to the last question: what is your objective? Is it victory, or something else?
What better path to victory then to alter the mind of your enemy until he is incapable of fighting you?
Our educational assets ought to therefore be shared. To sensor them in the name of security is foolish.
It's disruptive technology: not as good, way more accessible.
Seems misguided to me.