Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

php performance problem #4227

Closed
cl51287 opened this issue Jan 25, 2018 · 29 comments
Closed

php performance problem #4227

cl51287 opened this issue Jan 25, 2018 · 29 comments

Comments

@cl51287
Copy link

cl51287 commented Jan 25, 2018

php version is 7.0.24, protobuf extension is v3.4.1(also in v3.5.1),
When i test the performance use ab (nginx + php-fpm), system cpu become very high,

demo.php
<?php
require 'User.php';
require 'GPBMetadata/User.php';
new User;
user.proto
syntax = "proto3";
message  User {
    repeated uint32 uids =1;
    uint32 size = 2;
}

ab code is

ab -n 10000 -c 1000 http://127.0.0.1/demo.php

I found, the problem is $pool->internalAddGeneratedFile(hex2bin("***")); in GPBMetadata/User.php, this code take up 1ms cpu time, and every request all run this line code, so that system cpu become 30%, and if i add many new ProtoClass(10), the system cpu become 85%

@TeBoring
Copy link
Contributor

TeBoring commented Feb 2, 2018

Currently, the descriptor pool is built per request. For the second time you call new ProtoClass in the same request, the internalAddGeneratedPool will do nothing.

@cl51287
Copy link
Author

cl51287 commented Feb 6, 2018

@TeBoring I use release 3.5.1, but this phenomenon still appears. This phenomenon don't occur when i delete internalAddGeneratedPool this line.

@cl51287
Copy link
Author

cl51287 commented Feb 6, 2018

@TeBoring i know, the internalAddGeneratedPool will do nothing at the second time in the same request, but next request, it will be built again, it will cause cpu become very high, when many request visit server. Can this built action cache in php-fpm process ? Because the proto does not change in the different requests.

@zvuki
Copy link

zvuki commented Feb 22, 2018

@TeBoring Can it be cached in, say, apcu?

@zackangelo
Copy link

@TeBoring what was the use case in mind when having the DescriptorPool be rebuilt every request? Is it for long-running PHP servers?

Rebuilding the DescriptorPool every request is having a massively detrimental effect on performance for us because we have a ton of proto classes. Does the C extension have to do the same thing? Would you be amenable to us adding some methods to DescriptorPool that allow us to cache it externally?

@TeBoring
Copy link
Contributor

"Because the proto does not change in the different requests" Is this guaranteed? @cl51287
AFAIK, this is not true. Every request are free to execute any php files, which may contain conflicting protos.

@TeBoring
Copy link
Contributor

@zackangelo Yes, for long-running PHP servers

@TeBoring TeBoring added the php label Feb 27, 2018
@zackangelo
Copy link

@TeBoring we can guarantee in our case that the descriptors won't change. would you be opposed to us introducing a caching mechanism for the descriptor pool?

@cl51287
Copy link
Author

cl51287 commented Mar 2, 2018

@TeBoring yes, you are right, it may be change, but most of the time it does not change, as zackanglo and zvuki say , can it be cached in?

@TeBoring
Copy link
Contributor

TeBoring commented Mar 2, 2018 via email

@cl51287
Copy link
Author

cl51287 commented Mar 8, 2018

@TeBoring Can you tell me which option can cache it , i can't find it in document

@zackangelo
Copy link

@cl51287 the option doesn't exist, Paul is suggesting that as something we might build to enable this behavior.

@TeBoring how would you feel about a compiler mode that generated code that wrote bytes to a CodedOutputStream directly instead of relying the descriptor to do it dynamically?

@TeBoring
Copy link
Contributor

@zackangelo I don't think it's a good idea. We have tried to minimize php level code. Although your suggestion may improve the performance of pure php implementation, for cpp implementation, it will be terrible. With your proposal, most of the code will move from cpp to php.

@TeBoring
Copy link
Contributor

I would suggest add a global method to tell protobuf runtime not to deactivate descriptor pool after request is finished.

@cl51287
Copy link
Author

cl51287 commented Mar 23, 2018

I found protobuf compile the descriptor pool to memory for cpp implementation, is there a method can cache this object use pure php implementation?

@TeBoring
Copy link
Contributor

Not yet.

@cl51287
Copy link
Author

cl51287 commented Mar 27, 2018

Does this feature consider adding to protobuf? This compilation will take up many cpu, and there is no method to cache the result of compilation for php implementation.

@TeBoring
Copy link
Contributor

TeBoring commented Apr 7, 2018 via email

@cl51287
Copy link
Author

cl51287 commented Apr 9, 2018

thank you very much

@cl51287 cl51287 closed this as completed Apr 9, 2018
@cl51287
Copy link
Author

cl51287 commented Jul 11, 2018

@TeBoring Has this problem been solved?

@TeBoring
Copy link
Contributor

Sorry, I haven't added it.

@zackangelo
Copy link

@TeBoring wondering if you've given this any more thought? this is still a problem that heavily affects us in production.

@TeBoring
Copy link
Contributor

TeBoring commented Aug 2, 2019

Sorry for late reply. I'll add it soon.

@TeBoring TeBoring added P1 and removed P2 labels Aug 2, 2019
@cl51287
Copy link
Author

cl51287 commented Sep 4, 2019

Sorry for late reply. I'll add it soon.

Will the next version add this feature? @TeBoring

@zackangelo
Copy link

@TeBoring just wanted to ping and see if you've had a chance to look at this :)

@TeBoring
Copy link
Contributor

Fixed in #6899
Anyone wants to try that?

@TeBoring
Copy link
Contributor

To use it,

  1. Use the protoc in the change to regenerate code
  2. Add protobuf.keep_descriptor_pool_after_request=1 into php.ini

@cl51287
Copy link
Author

cl51287 commented Nov 20, 2019

@TeBoring Thank you very much, we are waiting for a long time, try it first.

@TeBoring
Copy link
Contributor

Should have been fixed by #6899

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants