Custom CDN - Nearest IP

How can I direct users to a certain server based on their location?

For example, I have 3 servers with the following ips:
68.109.23.45
19.80.71.60
120.13.14.156
(these are just examples and could be anything)

By knowing the user’s IP (for example, 67.102.123.13), how can I direct them to the closest server geographically, or in other words, the fastest?

I don’t want to do this for an entire site - only for large files for file hosting.

I have done something similar to this, where I switch a media server depending on the user country.

Firstly I have implemented this ip to country data.

Once I have the user country, I basically just do a switch statement to use server A for users in the Oceania world region, and server B for everyone else.

That could work - but what about for multiple servers within the same country? Is there a way to just ping the user? Would that be reliable for as a representation of speed?

A ping takes so long that it considerably slows down the request, basically rendering the whole reason for having CDN in the first place useless.

Also, if you want to use ping you should really ping the requester from all hosts within your CDN, which takes even longer. Plus the user might refuse to respond to ping request through a setting in a firewall/router (I do this), rendering the complete exercise pointless.

The best you can do with CDNs is best effort. Of course you’ll get it wrong sometimes, and the point is not to get everything right, but to get it right most of the time.

If there are multiple servers in the same country you could either send the requester to any one of them at random, or get a more detailed IP > location database and use latitude and longitude to determine which of the CDN hosts is physically closest to the requester (note that this doesn’t necessary have to be the fastest host for the user).

How about using something such as this:
Determine connection speed with php - Emanuele Feronato

As you say, even the closest server may not be the fastest. Maybe do something like this once per server per user?

That script streams 512 kb, which is probably more than all the data you want to provide through the CDN, defying the purpose of having a CDN in the first place.
Plus the user has to call the PHP script, you can’t just force them to execute it, so the idea won’t work anyway.

What kind of data are you looking to store in the CDN? Will be very large files or small files?

Large files. Over 500MB.