0

I would like to create a Cloud function to call a Postgres Cloud SQL DB. Currently I followed the documentation and create a Hikari based connection...

val config = new HikariConfig
    config.setJdbcUrl(jdbcURL)
    config.setDataSourceProperties(connProps)
    config.setMaximumPoolSize(10)
    config.setMinimumIdle(4)
    config.addDataSourceProperty("ipTypes", "PUBLIC,PRIVATE") // TODO: Make configureable
    println("Config created")
    val pool : DataSource = new HikariDataSource(config) // Do we really need Hikari here if it doesn't need pooling?
    println("Returning the datasource")
    Some(pool)

This works but it causes a 25 sec delay due to "cold start"s. I would like to try using PG driver directly and see if that is faster but I think that isn't possible thanks the the UNIX socket/SQL Cloud proxy stuff based on the documentation.

Is there a way to connect to Cloud SQL from a Cloud function using a basic PG Driver connection and not the Hikari stuff?

Jackie
  • 21,969
  • 32
  • 147
  • 289

2 Answers2

0

As mentioned in the thread:

With all "serverless" compute providers, there is always going to be some form of cold start cost that you can't eliminate. Even if you are able to keep a single instance alive by pinging it, the system may spin up any number of other instances to handle current load. Those new instances will have a cold start cost. Then, when load decreases, the unnecessary instances will be shut down.

you can now specify a minimum number of instances to keep active. This can help reduce (but not eliminate) cold starts. Read the Google Cloud blog and the documentation.

If you absolutely demand hot servers to handle requests 24/7, then you need to manage your own servers that run 24/7 (and pay the cost of those servers running 24/7). As you can see, the benefit of serverless is that you don't manage or scale your own servers, and you only pay for what you use, but you have unpredictable cold start costs associated with your project. That's the tradeoff.

For more information related to dependencies you can refer to the link provided by guillaume blaquiere.

Divyani Yadav
  • 1,030
  • 4
  • 9
  • This wasn't the question; the question is can I do it without the HikariCP – Jackie Jul 22 '22 at 14:56
  • Your question is poorly worded -- you are asking "can I do this without HiakriCP", but what you really want is to reduce the coldstart time of your function. I will leave a longer answer about why getting rid of HikariCP probably won't help. – kurtisvg Jul 22 '22 at 16:17
0

To answer your exact question:

Can I connect without using HikariCP?

The answer is sure; you can use any number of connection pooling libraries avaible in Java. The examples often show HikariCP because it is far and away the most popular and highest performing.

So it's unlikely that switching connection pools will improve your performance. A slightly different question implied by your first question might be:

Can I connect without using a connection pool?

And again the answer is sure, you could use the driver directly -- but you probably shouldn't. Connection creation and management is expensive (and hard), and using a connection pool is a best practice. I wouldn't consider code "production quality" without one. While it might save you boot time, it's likely to introduce more overhead and latency into the request itself, costing you more overall. Additionally, it'll remove helpful error handling and retries around connections that you'll now have to deal with yourself.

So it seems you question really might be:

How can I reduce my cold start time?

Well with a start time of 25 seconds, the problem likely isn't limited to just Hikari. I would check out this GCP doc page on performance, and look into other articles on how to improve start up time for JVMs or your specific frameworks.

However, one way that HikariCP might be impacting your start up time is that HikariCP blocks on the connection creation until the initialization is complete. There are a few things you can do to improve this (but likely will only help, not eliminate the 25s cold start)

  1. You can lower your number of connections to 1. Cloud function instances only handle requests one at a time, so specifying a min-idle of 4 and a max connection to 10 is likely leading to wasted connections.

  2. You can move the initialization of Hikari to happen outside of your start up. The GCP docs page I mentioned above shows how to use lazy initialization, so expensive object's aren't created until you need them. This will move the cost of initializing Hikari out of your functions start up. This could make the first request that calls it more expensive -- if that is a concern, I would suggest combining lazy initialization along with triggering that initialization in async way on start up. This way the pool is created in the background, without blocking startup.

  3. As an alternative to #2, you could also lower min-idle connections to 0 - e.i., initialize the Hikari Pool with 0 connections in it. While this might be easier to implement, it will mean that requests without a warmed up connection will have to wait for a new connection to be established. (which makes #2 more optimal in terms of performance).

kurtisvg
  • 3,412
  • 1
  • 8
  • 24