facebook / facebook/hhvm

Memcache connects to all servers in the pool, even if it never uses the connection

Open
#6,904 0 comments 0 reactions 0 assignees View on GitHub
mid-pri php5 incompatibility php7 incompatibility
Dominant language
C++
Stars
18.7k
Forks
3.1k
Avg merge
1h 47m
Merged PRs (30d)
2

Description

### HHVM Version

HipHop VM 3.12.1 (rel)
Compiler: tags/HHVM-3.12.1-0-gf516f1bb9046218f89885a220354c19dda6d8f4d
Repo schema: f2e5f39b2ad4a08bcbd90b5d8bcb580f40fba6c8
### Standalone code, or other way to reproduce the problem

Start three memcached instances:

```
memcached -d -U 0 -p 22220
memcached -d -U 0 -p 22221
memcached -d -U 0 -p 22222
```

Code to add all three to a single pool:

``` php
$memcache = new Memcache();
$memcache->addServer( '127.0.0.1', 22220 );
$memcache->addServer( '127.0.0.1', 22221 );
$memcache->addServer( '127.0.0.1', 22222 );
```

Run the above code with HHVM, then check the number of connections with `netstat -na|grep 2222`. You'll notice that connections were made to all three memcached instances, even though we never used the connection.

Then do the same thing with PHP 5.6.19. No connections were made. The php.net docs outline this behavior, from http://php.net/manual/en/memcache.addserver.php -

> When using this method (as opposed to Memcache::connect() and Memcache::pconnect()) the network connection is not established until actually needed. Thus there is no overhead in adding a large number of servers to the pool, even though they might not all be used.

I haven't tested it, but PHP 7 should have the same connect on demand behavior.
### Expected result

I expected HHVM to behave the same as PHP, specifically: not connecting to a server in the pool until that connection is going to be used.
### Actual result

HHVM will always connect to every server in the memcache pool, even if it never uses the connection.

---

I discovered this while confirming that #4992 ( and this ) are the source of our increased network traffic when using HHVM compared to PHP servers. I'm seeing HHVM generate roughly ~3X the amount of network traffic relative to PHP, due to these memcache differences.

There is a performance component to this as well. I recorded the memcache traffic from HHVM with tcpdump and noticed that it will not issue any requests until it has established connections with all of the memcache servers in the pool.

If you had code that did:
- defined a pool with memcache servers mem1, mem2, mem3, mem4, and mem5
- requests data from memcache that happens to be on mem2

Then HHVM will do the following:
- connect to mem1
- connect to mem2
- connect to mem3
- connect to mem4
- connect to mem5
- requests data from mem2

PHP will do:
- connect to mem2
- requests data from mem2

And in our case most requests don't have to worry about connecting, because of persistent connection support in PHP. Which HHVM doesn't have ( see #4992 again ).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.