How We Built Uber Engineering’s Highest Query per Second Service (2016)
eng.uber.com
eng.uber.com
https://medium.com/@buckhx/unwinding-uber-s-most-efficient-s...
I am surprised they're scanning each city linearly, even a crude index (such as boxing), or a binary search would greatly improve the lookup time. I guess if the data fits into the cpu cache the order these are scanned doesn't matter so much?
See https://news.ycombinator.com/item?id=16084090 for the brief discussion yesterday.
S2 is fantastic for geofencing. Arbitrary regions can be covered by a set of S2 cells of varying level. A point (lat/lon) can be converted to a S2 cell of the smallest level (around a cm^2 of area on the sphere). Checking to see if one S2 cell is contained in another amounts to searching an integer range, since all children of a given S2 cell have IDs that fall within a fixed ranged. See also [2]
[0] https://github.com/google/s2-geometry-library-java
[1] https://github.com/golang/geo
[2] http://blog.christianperone.com/2015/08/googles-s2-geometry-...
So, instead of using a quadtree (because it's "complicated"), they chose to make their own two-level tree requiring O(N) linear scans at both levels, as opposed to O(1) with a simple trick.
"100s" of linear polygon scans could likely turn into a few, plus a quad tree or spatial grid hash lookup. I don't quite understand why those approaches are considered "complex?" Every simplistic game engine does this as soon as it implements collision.
Finally, choosing languages for workloads is fine. Python and JavaScript are famously non-threaded. But what about Java, C#, or C++? And why is the index updated in process, instead of a new process spinning up with the new index, and then switching over who takes requests?
Not saying what they built doesn't work, just curious about options.
Python has famously misunderstood threading support. It is certainly single threaded sometimes (or rather multi threaded but only one can run at a time even on a multi core machine). But it can be usefully multithreaded if most of your computation is done with a C extension module that releases the GIL while it's being called e.g. numpy. If such a wrapper for the C++ S3 library exists (I haven't checked) it would be viable for this task.
I agree that choosing languages for work loads is fine though, and admittedly even in the best case Python would still not be as efficient as Go.
If anyone's used PostGIS with a similar level of traffic/latency requirements could you comment on your experience?
Query-wise, PostGIS should be able to use geohashes which can do these lookups in O(1) time (S2 geometry would be similar). That said, indexing scales terrible with geohashing/S2 at high granularity levels, though they wouldn't need something particularly granular for this (seems fine to be off by tens or hundreds of meters)
He also talked about how many problems it had caused them and all that fun stuff. I left that meetup thinking two things: 1. Who the fuck breaks stuff just to use a cool new language? 2. Good lord, I really don't ever want to work on this team. It's chaos.
What about Uber's business model impacted this choice of algorithm?
Edit: left only the unanswered question
Have you guys looked at moving to rust for any services?
I say that as someone who assiduously avoids using Uber's services, who finds what I know of their culture to be odious, and who has strongly criticized some of their other technical decisions, so please don't construe my comment as fanboy defensiveness.