Hi we're working a map reduce script trying to pro...
# suitescript
p
Hi we're working a map reduce script trying to process 2000 transactions (each has 1 line) and the performance I'm getting roughly around 2 records per second. Is this the fastest. We have SC and I’m having it run around 7 concurrency which I find this performance scaling very alarming. Anyone has any thoughts? This is via map/reduce.
a
Normally it does not get a lot better than that, NetSuite is not a traditional DB, every transaction line is inter-connected to a bunch of other tables and those table are also inter-connected, lot of things happening in the background. If you want to do an experiment, find or create a transaction, let say an Invoice with 1000 or 2000 lines, de-activate any scripts or workflows, EDIT and SAVE in the UI, it will take closer to 5 minutes if not more to save, without changing/updating a single thing.
b
Application Performance Management is the standard answer for performance monitoring to see what cost each script/workflow is taking
a
what does "process" mean are you loading and editing? run queries to get additional data for each transaction??? you've told us nothing. "around 7 concurrency" ??? all that said you're concerned that a process takes 15minutes?
p
Process- simply creating records. (Ex. Invoices) there's no data lookups. Yes concerned because I have lots of records, batches. At this pace I would only hit 3,600 transactions an every half hour. And if I have batches to process (say ten thousands, it's taking way too long
a
I'd check your scripted records for the transaction type and see what things you have running on beforeSubmit workflows / other User event scripts
a
If you are transforming SOs to Invoices and you have a large number of those, perhaps you need to look at the business process itself, there is more than one way to skin a cat... Per instance you could have a UE script that transform the SO to Invoice once a particular condition is met and you automate that portion without having to use a Map Reduce or having to handle thousands of SOs in a cumulative way.
p
I was able to save a few ms to like 2.2 records per second without any scripts/workflows. There's no transformation. Just simple standalone invoice or cash sale with a single line item
I don't really have any other path besides different way to load records via m/r or csv import via task. I'm not sure the performance via task import. But the reason for m/r was I could add some data error handling for troubleshooting external transactions importing into NetSuite.
a
It will not get better than that, NetSuite is not a traditional relational database, you will never archive a throughput similar to MySQL, MariaDB, Postgres, never ever....
One important thing to know tho, a well designed Map Reduce can run for days without ever reaching any governance limits, you do not need batches, you can literally process millions of records in one run.
a
I'm wondering if the overhead of creating the MR stages is a factor given your processing is so simple, normally I'd just ignore that, but it might be worth testing. assuming you're doing 1 invoice per map stage you have 1k governance per map stage and you're only using 20 i think for a transaction save? so would it be feasible chunk your data into groups of say 40? that would still only use 800 governance but you'd have way fewer map stage instances. I have no idea if that will actually help but if the data chunking is easier enough for you to do then it should be worth a quick test.
p
My current saves are in reduce. I could try to do it in map, but the parallelism happen in either map/reduce doesn't if? So does it really matter if it happen in the map or reduce?
a
not at all, i just assumed the map cos that's simple... reduce is actually better you have 5k governance instead of 1k... so you could potentially do 200 per reduce stages
i mean if you're actually leveraging both the map and reduce then I guess you can't simply chunk the data since presumably you're doing something already to group the data between map and reduce
p
I tried chunking by batching multiple invoices in a reduce, like 20, but the whole concurrency broke and it didn't distribute the workload across concurrency wells
If I had one record per reduce, it split the work across concurrency. Batching chunks of 10/20 records, I notice the reduce only ran on 2 vs the 7 allotted. 5 of them would finish too early while the remaining two was still running.
a
I don't think you have a clear understanding of NetSuite's concurrency model
whatever batch size it is doesnt' really matter... each reduce "batch" is just a reduce batch... however many your data means you have is how many batches you have... when there's availability a new reduce instance will fire up and take whatever the next batch is. they're don't sync up or anything, once a reduce stage has started its effectively independent of the rest of the reduce stages and it will finish whenever it finishes at which point it will free up a spot for whichever reduce stage is waiting
they used to be called queues rather than concurrency, and that mental model I still think works well to understand what's actually happening.
oh sorry, you just mean it wasn't efficient...
yeah there's no way to account for that... if your data set is big enough it won't matter though
p
Yes I understand. But when I batch. However it’s splitting the 1000 records across the different queue/concurrency. For whatever reason it just goes to 2. Vs the other 5. The distribution was weird when I batch 20 records per reduce.
a
it might have just been some other unrelated process triggered at the same time and stole some of the queues πŸ˜‰
p
It took longer. I think it might be a bug. Because if I had single recorder per reduce. It distributed fine and to what you explained.
a
where/how is the data coming into NS?
p
I had testing very specific. It was an odd behavior. I looked at the status and 5 just stopped and finished while only 2 was running. Hmm let me double check and change to high priority and make sure I have no other map/reduce running. I could be overlooking that.
It a simple csv file.
a
your loading the csv file lines into memory and then using a map reduce per line? to create invoices?
p
Yes.
I had previously had some lookup in the map. And lookup ran almost instantly. It just saving.
a
k and you ruled out csv import task because... you want error handling /validation or something?
p
Correct.
a
... how many data elements are you setting? like how many fields are there per invoice/line combination? approximatey? 10? 100? 1000?
p
I'm going to test the csv tomorrow to see the performance there. But just isn't ideal without error handling/logging.
a
oh when you do the record create are you using dynamic mode?
p
Fields about 15 fields. No lookups. All single lines.
a
... so a little crazier option... create a new custom record - Invoice Import Map create your 15 fields on that record map reduce to create those custom records instead of your invoices and have a UE aftersubmit on your new custom record which takes those 15 data elements and creates the invoice.
(I'm pretty sure dynamic mode comes with a performance cost, but its usually negligible so I'd never normally worry about it but might be a quick fix to just use static mode)
p
i can do a quick test.
i do notice custom record performance is a lot faster!
πŸ‘ 1
so are you suggesting create custom record and ahve UE script triger creation of hte invoice?
a
exactly
p
i haven't tested but can do a quick test as my mr import tool is a CONFIG so i just need to make a new config to load and can see metrics there
Duration (seconds) 409.751 Records Per Minute 146.43039309 Governance Units Used 46 Avg Processing Time 2.451301 Records Per Governance Unit 21.73913043 Performance Status Info Governance Units Used: 46 units [Good] Action: Performance is optimal Avg Processing Time: 2.4513 sec/record [Critical] Action: Investigate slow transformations Records Per Gov Unit: 21.74 records/unit [Good (Efficient)] Action: Efficiency is excellent
there's no transformation so ignore taht text but this is the number benchmarks i'm working with
a
that's 146 per minute? i thought you said it was 2? or is this custom records?
p
2 per second
a
oh duh right
p
yea dynamic/no dynamic is neligible. in my case it behave a bit worse. probably an outlier
πŸ‘ 1
n
@Phi-My Tran Not sure if this is suggested already, but you can also try using the promise version for save. It should shave off the time the script waits for the response to return for the save.
p
thanks. i was going to try that next. I was able to double the concurrency from 7 to 15 , and performance did gain upward to 742 records per minute average to 9 records a second. so sounds like SC+ is the way to go.
n
Use promise version of the save as well.
p
n
No, it is on server side as well. I have used it in my MR/Scheduled scripts
ty1 1
b
Scripts still wait for the promise before stopping. Your function might return faster, but the script engine still needs to run to wait.
πŸ’― 1