[MUSIC PLAYING]
MARTIN: Hey, Craig.
CRAIG: Hey, Martin.
What are you working on?
MARTIN: I built a web app and a mobile app that display
info about famous artists.
It is backed by a REST API running on Cloud Run.
But users are reporting that it's sometimes slow.
Can you help me speed it up?
CRAIG: Yeah, absolutely.
It sounds like you might need a caching layer.
Let me show you how it's done.
MARTIN: Great.
[MUSIC PLAYING]
MARTIN: All right, Craig, so here is my API.
If I hit the URL here, it takes three seconds to respond.
CRAIG: Three seconds?
What does your code look like?
MARTIN: [LAUGHS] Yeah, here it is.
This call here runs a complex database query.
It takes several seconds to complete.
CRAIG: I see.
So you could try to save recently accessed artists
in a cache, and that would make your slow database query
run less often.
And it looks like your data structure here
is pretty simple.
It's just an ID that points to an object.
And that really lends itself to a key value cache.
MARTIN: Sounds good.
Can you show me how to do it?
CRAIG: Absolutely.
Click Memorystore in the Cloud console.
Memorystore is built to handle exactly this kind of caching.
MARTIN: I will pick Redis for now.
And I'm enabling Memorystore in this project.
CRAIG: Great.
Now, click Create Instance, and give it an instance name
and display name.
And then for the rest of the fields, the defaults are fine,
so you should be able to click the Create button.
Now your Redis server is being initialized.
And this server sits in a virtual private cloud.
So it's not accessible from the outside internet.
That means the next thing we need to do
is set up a connector so that your Cloud Run
service can connect to this virtual private cloud.
And to do that, first pick VPC network
in the navigation sidebar.
Then click Serverless VPC Access.
Now, click Create Connector.
Give it the name my-vpc-connector.
Under Network, pick default. And under subnet, Pick Custom IP
range.
Now in the text box, enter the suggested value of 10.8.0.0.
That works great.
And click the Create button.
Now, let's head back over to Memorystore,
and copy the IP address of the Redis instance
that we just created.
Now, in your deployment script, add $REDIS_HOST, $REDIS_PORT,
and vpc-connector as environment variables.
MARTIN: Now that is done.
I will enter the code snippet you sent me.
CRAIG: Awesome.
That subnet creates a Redis client
object so that your other code can
use that to access the cache.
And then instead of calling getArtistsFromDatabase,
we can call a new function, getArtistFromCache.
Now, in this new getArtistFromCache method,
the first three lines simply make
the Redis client use promises instead of callbacks.
And this just makes your code easier to read.
Then the code checks to see if the artist with the given ID
is in the cache.
If it isn't, it calls getArtistsFromDatabase and puts
that artist in the cache.
Finally, it reads the artist's record from the cache
and returns it.
MARTIN: I'm deploying the updated code to Cloud Run.
Very good.
The code is now deployed.
I'm hitting the URL now.
Oh, it's still as slow as before, Craig.
CRAIG: Yes, of course, because the artist is not yet
in the cache on that first request.
But if you reload the page, I think it'll be a lot faster.
MARTIN: I'm reloading.
Oh, that was a lot faster.
Cool.
But what if I need to update that artist
record in the database?
CRAIG: Well, then you'll need to update it in the cache, too.
I sent you some more code for that.
Did you get it?
MARTIN: Ah, yes.
Let's see.
Entering it now.
CRAIG: Great.
So this method uses the request payload
to update both the cache value and any database records.
So the cache is never stale.
MARTIN: Excellent.
Let's redeploy the API.
Now back to Postman.
Here, I have a put request that will add the field movement
to Frida Kahlo's artist record.
She belonged to the surrealism movement.
CRAIG: Well, that's perfect, because you're
going to have a surreally fast API with all this caching.
MARTIN: [LAUGHS] Maybe don't quit your day job, Craig.
Now, to reread that artist's data.
Ah, and here it is with a new movement field added.
And it was very quick served from the cache.
Thanks for helping me speed up my API, Craig.
CRAIG: Happy to help.
Now, right now, your code is using
the read-through and write-through caching
strategies.
And they work pretty well for most applications.
But you might also want to search
online for some other caching patterns in case
those work better for your app.
Now, also remember that your code can never
count on this object being in the cache.
That's why we still have the database backing it up.
When a cache fills up, it can kick out objects at any time.
MARTIN: Oh, right.
Thank you for that reminder, Craig.
And thank you, everyone, for watching.
You will find a link to the code and
to the Memorystore documentation in the description below.
Please let us know in the comments
if you found this episode useful or if you have suggestions
for future episodes.
CRAIG: Happy caching.
[MUSIC PLAYING]